summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmeer J <52414509+ameerj@users.noreply.github.com>2023-11-27 03:08:53 +0100
committerGitHub <noreply@github.com>2023-11-27 03:08:53 +0100
commit1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a (patch)
treec219aacab776c0a1e3956614b60a01fa2f6164cb
parentshader_recompiler: Align SSBO offsets in GlobalMemory functions (diff)
parentMerge pull request #11535 from GPUCode/upload_cmdbuf (diff)
downloadyuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.gz
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.bz2
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.lz
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.xz
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.zst
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.zip
-rwxr-xr-x.ci/scripts/android/build.sh9
-rwxr-xr-x.ci/scripts/android/upload.sh12
-rw-r--r--.git-blame-ignore-revs5
-rw-r--r--.github/workflows/android-build.yml2
-rw-r--r--.gitmodules6
-rw-r--r--CMakeLists.txt2
-rw-r--r--CMakeModules/FindSimpleIni.cmake19
-rw-r--r--CMakeModules/Findinih.cmake27
-rw-r--r--dist/languages/.tx/config5
-rw-r--r--dist/languages/ar.ts1651
-rw-r--r--dist/languages/ca.ts848
-rw-r--r--dist/languages/cs.ts848
-rw-r--r--dist/languages/da.ts848
-rw-r--r--dist/languages/de.ts995
-rw-r--r--dist/languages/el.ts848
-rw-r--r--dist/languages/es.ts888
-rw-r--r--dist/languages/fr.ts876
-rw-r--r--dist/languages/hu.ts1669
-rw-r--r--dist/languages/id.ts848
-rw-r--r--dist/languages/it.ts862
-rw-r--r--dist/languages/ja_JP.ts926
-rw-r--r--dist/languages/ko_KR.ts850
-rw-r--r--dist/languages/nb.ts850
-rw-r--r--dist/languages/nl.ts850
-rw-r--r--dist/languages/pl.ts850
-rw-r--r--dist/languages/pt_BR.ts884
-rw-r--r--dist/languages/pt_PT.ts882
-rw-r--r--dist/languages/ru_RU.ts850
-rw-r--r--dist/languages/sv.ts848
-rw-r--r--dist/languages/tr_TR.ts850
-rw-r--r--dist/languages/uk.ts850
-rw-r--r--dist/languages/vi.ts850
-rw-r--r--dist/languages/vi_VN.ts850
-rw-r--r--dist/languages/zh_CN.ts868
-rw-r--r--dist/languages/zh_TW.ts850
-rw-r--r--externals/CMakeLists.txt10
-rw-r--r--externals/inih/CMakeLists.txt13
m---------externals/inih/inih0
m---------externals/simpleini0
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/android/app/build.gradle.kts5
-rw-r--r--src/android/app/src/main/AndroidManifest.xml1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt8
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt8
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt52
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt5
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt30
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt61
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt42
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt8
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt38
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt92
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt12
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt97
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt40
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt45
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt34
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt24
-rw-r--r--src/android/app/src/main/jni/CMakeLists.txt12
-rw-r--r--src/android/app/src/main/jni/android_config.cpp70
-rw-r--r--src/android/app/src/main/jni/android_config.h41
-rw-r--r--src/android/app/src/main/jni/android_settings.cpp (renamed from src/android/app/src/main/jni/uisettings.cpp)2
-rw-r--r--src/android/app/src/main/jni/android_settings.h (renamed from src/android/app/src/main/jni/uisettings.h)2
-rw-r--r--src/android/app/src/main/jni/config.cpp330
-rw-r--r--src/android/app/src/main/jni/config.h47
-rw-r--r--src/android/app/src/main/jni/default_ini.h511
-rw-r--r--src/android/app/src/main/jni/emu_window/emu_window.cpp8
-rw-r--r--src/android/app/src/main/jni/emu_window/emu_window.h4
-rw-r--r--src/android/app/src/main/jni/native.cpp48
-rw-r--r--src/android/app/src/main/jni/native.h8
-rw-r--r--src/android/app/src/main/jni/native_config.cpp23
-rw-r--r--src/android/app/src/main/jni/native_log.cpp31
-rw-r--r--src/android/app/src/main/res/drawable/ic_audio.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_code.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_graphics.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_system_settings.xml9
-rw-r--r--src/android/app/src/main/res/layout-w600dp/fragment_about.xml233
-rw-r--r--src/android/app/src/main/res/layout/card_home_option.xml4
-rw-r--r--src/android/app/src/main/res/layout/fragment_about.xml10
-rw-r--r--src/android/app/src/main/res/layout/fragment_emulation.xml11
-rw-r--r--src/android/app/src/main/res/layout/fragment_home_settings.xml9
-rw-r--r--src/android/app/src/main/res/layout/fragment_search.xml1
-rw-r--r--src/android/app/src/main/res/layout/list_item_setting.xml72
-rw-r--r--src/android/app/src/main/res/layout/list_item_setting_switch.xml8
-rw-r--r--src/android/app/src/main/res/layout/list_item_settings_header.xml3
-rw-r--r--src/android/app/src/main/res/resources.properties1
-rw-r--r--src/android/app/src/main/res/values-ar/strings.xml385
-rw-r--r--src/android/app/src/main/res/values-ckb/strings.xml336
-rw-r--r--src/android/app/src/main/res/values-de/strings.xml119
-rw-r--r--src/android/app/src/main/res/values-es/strings.xml180
-rw-r--r--src/android/app/src/main/res/values-fr/strings.xml180
-rw-r--r--src/android/app/src/main/res/values-he/strings.xml367
-rw-r--r--src/android/app/src/main/res/values-hu/strings.xml402
-rw-r--r--src/android/app/src/main/res/values-it/strings.xml192
-rw-r--r--src/android/app/src/main/res/values-ja/strings.xml218
-rw-r--r--src/android/app/src/main/res/values-ko/strings.xml273
-rw-r--r--src/android/app/src/main/res/values-nb/strings.xml113
-rw-r--r--src/android/app/src/main/res/values-pl/strings.xml81
-rw-r--r--src/android/app/src/main/res/values-pt-rBR/strings.xml210
-rw-r--r--src/android/app/src/main/res/values-pt-rPT/strings.xml192
-rw-r--r--src/android/app/src/main/res/values-ru/strings.xml159
-rw-r--r--src/android/app/src/main/res/values-uk/strings.xml90
-rw-r--r--src/android/app/src/main/res/values-vi/strings.xml340
-rw-r--r--src/android/app/src/main/res/values-zh-rCN/strings.xml138
-rw-r--r--src/android/app/src/main/res/values-zh-rTW/strings.xml137
-rw-r--r--src/android/app/src/main/res/values/arrays.xml2
-rw-r--r--src/android/app/src/main/res/values/strings.xml9
-rw-r--r--src/android/app/src/main/res/xml/locales_config.xml17
-rw-r--r--src/audio_core/adsp/apps/opus/opus_decode_object.cpp214
-rw-r--r--src/audio_core/adsp/apps/opus/opus_decoder.cpp4
-rw-r--r--src/audio_core/adsp/apps/opus/opus_multistream_decode_object.cpp222
-rw-r--r--src/audio_core/opus/decoder.cpp358
-rw-r--r--src/audio_core/opus/decoder.h106
-rw-r--r--src/audio_core/opus/decoder_manager.cpp204
-rw-r--r--src/audio_core/opus/decoder_manager.h76
-rw-r--r--src/audio_core/opus/hardware_opus.cpp482
-rw-r--r--src/audio_core/opus/hardware_opus.h90
-rw-r--r--src/audio_core/sink/cubeb_sink.cpp2
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp2
-rw-r--r--src/audio_core/sink/sink_stream.cpp12
-rw-r--r--src/audio_core/sink/sink_stream.h6
-rw-r--r--src/common/arm64/native_clock.cpp21
-rw-r--r--src/common/page_table.cpp30
-rw-r--r--src/common/page_table.h17
-rw-r--r--src/common/settings.cpp6
-rw-r--r--src/common/settings.h46
-rw-r--r--src/common/settings_common.h1
-rw-r--r--src/common/settings_input.cpp9
-rw-r--r--src/common/settings_input.h7
-rw-r--r--src/core/CMakeLists.txt26
-rw-r--r--src/core/arm/arm_interface.cpp16
-rw-r--r--src/core/core_timing.cpp2
-rw-r--r--src/core/core_timing.h2
-rw-r--r--src/core/debugger/gdbstub.cpp233
-rw-r--r--src/core/file_sys/romfs.cpp44
-rw-r--r--src/core/file_sys/romfs.h9
-rw-r--r--src/core/hid/emulated_console.h8
-rw-r--r--src/core/hid/emulated_controller.cpp144
-rw-r--r--src/core/hid/emulated_controller.h4
-rw-r--r--src/core/hid/hid_core.cpp5
-rw-r--r--src/core/hid/hid_types.h110
-rw-r--r--src/core/hid/input_interpreter.cpp11
-rw-r--r--src/core/hid/input_interpreter.h4
-rw-r--r--src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp13
-rw-r--r--src/core/hle/kernel/board/nintendo/nx/k_system_control.h7
-rw-r--r--src/core/hle/kernel/k_capabilities.cpp39
-rw-r--r--src/core/hle/kernel/k_capabilities.h17
-rw-r--r--src/core/hle/kernel/k_device_address_space.cpp4
-rw-r--r--src/core/hle/kernel/k_device_address_space.h10
-rw-r--r--src/core/hle/kernel/k_memory_layout.h8
-rw-r--r--src/core/hle/kernel/k_memory_manager.cpp12
-rw-r--r--src/core/hle/kernel/k_page_table.cpp3519
-rw-r--r--src/core/hle/kernel/k_page_table.h542
-rw-r--r--src/core/hle/kernel/k_page_table_base.cpp5716
-rw-r--r--src/core/hle/kernel/k_page_table_base.h759
-rw-r--r--src/core/hle/kernel/k_process.cpp18
-rw-r--r--src/core/hle/kernel/k_process.h14
-rw-r--r--src/core/hle/kernel/k_process_page_table.h480
-rw-r--r--src/core/hle/kernel/k_server_session.cpp2
-rw-r--r--src/core/hle/kernel/k_system_resource.cpp2
-rw-r--r--src/core/hle/kernel/k_thread_local_page.cpp4
-rw-r--r--src/core/hle/kernel/process_capability.cpp389
-rw-r--r--src/core/hle/kernel/process_capability.h266
-rw-r--r--src/core/hle/kernel/svc/svc_memory.cpp6
-rw-r--r--src/core/hle/kernel/svc/svc_physical_memory.cpp9
-rw-r--r--src/core/hle/kernel/svc/svc_process_memory.cpp3
-rw-r--r--src/core/hle/kernel/svc/svc_query_memory.cpp8
-rw-r--r--src/core/hle/result.h31
-rw-r--r--src/core/hle/service/acc/acc.cpp56
-rw-r--r--src/core/hle/service/am/am.cpp91
-rw-r--r--src/core/hle/service/am/am.h3
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.cpp3
-rw-r--r--src/core/hle/service/am/applets/applet_controller.h2
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.cpp3
-rw-r--r--src/core/hle/service/am/applets/applets.h24
-rw-r--r--src/core/hle/service/btm/btm.cpp56
-rw-r--r--src/core/hle/service/friend/friend.cpp13
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.cpp42
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.h43
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.cpp9
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h4
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp10
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h6
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp54
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h6
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp10
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h6
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h6
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp588
-rw-r--r--src/core/hle/service/hid/controllers/npad.h205
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp88
-rw-r--r--src/core/hle/service/hid/controllers/palma.h8
-rw-r--r--src/core/hle/service/hid/controllers/seven_six_axis.cpp (renamed from src/core/hle/service/hid/controllers/console_sixaxis.cpp)38
-rw-r--r--src/core/hle/service/hid/controllers/seven_six_axis.h (renamed from src/core/hle/service/hid/controllers/console_sixaxis.h)31
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.cpp413
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.h111
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h6
-rw-r--r--src/core/hle/service/hid/controllers/xpad.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/xpad.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp2861
-rw-r--r--src/core/hle/service/hid/hid.h212
-rw-r--r--src/core/hle/service/hid/hid_debug_server.cpp159
-rw-r--r--src/core/hle/service/hid/hid_debug_server.h26
-rw-r--r--src/core/hle/service/hid/hid_firmware_settings.cpp99
-rw-r--r--src/core/hle/service/hid/hid_firmware_settings.h54
-rw-r--r--src/core/hle/service/hid/hid_server.cpp2371
-rw-r--r--src/core/hle/service/hid/hid_server.h149
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp539
-rw-r--r--src/core/hle/service/hid/hid_system_server.h63
-rw-r--r--src/core/hle/service/hid/hid_util.h146
-rw-r--r--src/core/hle/service/hid/irs.cpp7
-rw-r--r--src/core/hle/service/hid/irs.h5
-rw-r--r--src/core/hle/service/hid/irsensor/clustering_processor.cpp16
-rw-r--r--src/core/hle/service/hid/irsensor/clustering_processor.h9
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.cpp2
-rw-r--r--src/core/hle/service/hid/irsensor/moment_processor.cpp123
-rw-r--r--src/core/hle/service/hid/irsensor/moment_processor.h34
-rw-r--r--src/core/hle/service/hid/resource_manager.cpp241
-rw-r--r--src/core/hle/service/hid/resource_manager.h111
-rw-r--r--src/core/hle/service/hid/ring_lifo.h6
-rw-r--r--src/core/hle/service/ldn/ldn.cpp10
-rw-r--r--src/core/hle/service/ldr/ldr.cpp45
-rw-r--r--src/core/hle/service/nfc/common/device_manager.cpp3
-rw-r--r--src/core/hle/service/nvdrv/devices/ioctl_serialization.h159
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp82
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h20
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp42
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h12
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp115
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h29
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp117
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h35
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp87
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp7
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp13
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp47
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h12
-rw-r--r--src/core/hle/service/nvnflinger/buffer_item.h2
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp27
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_consumer.h9
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_core.cpp12
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_core.h3
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_producer.cpp19
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_producer.h3
-rw-r--r--src/core/hle/service/nvnflinger/buffer_slot.h2
-rw-r--r--src/core/hle/service/nvnflinger/buffer_transform_flags.h2
-rw-r--r--src/core/hle/service/nvnflinger/consumer_base.cpp20
-rw-r--r--src/core/hle/service/nvnflinger/consumer_base.h2
-rw-r--r--src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp29
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp22
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.h2
-rw-r--r--src/core/hle/service/nvnflinger/status.h2
-rw-r--r--src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp34
-rw-r--r--src/core/hle/service/nvnflinger/ui/graphic_buffer.h25
-rw-r--r--src/core/hle/service/set/set_sys.cpp96
-rw-r--r--src/core/hle/service/set/set_sys.h36
-rw-r--r--src/core/hle/service/sockets/bsd.cpp77
-rw-r--r--src/core/hle/service/sockets/bsd.h2
-rw-r--r--src/core/hle/service/time/clock_types.h5
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp2
-rw-r--r--src/core/memory.cpp31
-rw-r--r--src/core/memory/cheat_engine.cpp12
-rw-r--r--src/frontend_common/CMakeLists.txt10
-rw-r--r--src/frontend_common/config.cpp1008
-rw-r--r--src/frontend_common/config.h211
-rw-r--r--src/input_common/drivers/gc_adapter.cpp8
-rw-r--r--src/input_common/drivers/joycon.cpp8
-rw-r--r--src/input_common/drivers/sdl_driver.cpp20
-rw-r--r--src/input_common/drivers/sdl_driver.h2
-rw-r--r--src/input_common/drivers/udp_client.cpp8
-rw-r--r--src/shader_recompiler/CMakeLists.txt1
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_image.cpp6
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_image.cpp6
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp56
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_instructions.h2
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h2
-rw-r--r--src/shader_recompiler/frontend/ir/modifiers.h2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/texture_gradient.cpp29
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp1
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp10
-rw-r--r--src/shader_recompiler/ir_opt/passes.h1
-rw-r--r--src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp79
-rw-r--r--src/shader_recompiler/profile.h1
-rw-r--r--src/video_core/CMakeLists.txt5
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h102
-rw-r--r--src/video_core/buffer_cache/buffer_cache_base.h4
-rw-r--r--src/video_core/buffer_cache/usage_tracker.h79
-rw-r--r--src/video_core/engines/fermi_2d.cpp4
-rw-r--r--src/video_core/engines/maxwell_3d.cpp2
-rw-r--r--src/video_core/fence_manager.h5
-rw-r--r--src/video_core/host1x/codecs/codec.cpp329
-rw-r--r--src/video_core/host1x/codecs/codec.h39
-rw-r--r--src/video_core/host1x/codecs/h264.cpp4
-rw-r--r--src/video_core/host1x/codecs/h264.h1
-rw-r--r--src/video_core/host1x/ffmpeg/ffmpeg.cpp419
-rw-r--r--src/video_core/host1x/ffmpeg/ffmpeg.h213
-rw-r--r--src/video_core/host1x/nvdec.cpp2
-rw-r--r--src/video_core/host1x/nvdec.h2
-rw-r--r--src/video_core/host1x/vic.cpp62
-rw-r--r--src/video_core/host1x/vic.h4
-rw-r--r--src/video_core/query_cache/query_cache.h2
-rw-r--r--src/video_core/renderer_null/null_rasterizer.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h17
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h1
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp14
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp135
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp36
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h21
-rw-r--r--src/video_core/renderer_vulkan/vk_fsr.cpp24
-rw-r--r--src/video_core/renderer_vulkan/vk_fsr.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_master_semaphore.cpp29
-rw-r--r--src/video_core/renderer_vulkan/vk_master_semaphore.h14
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp24
-rw-r--r--src/video_core/renderer_vulkan/vk_query_cache.cpp13
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp20
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.cpp28
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.h21
-rw-r--r--src/video_core/renderer_vulkan/vk_smaa.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp18
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h1
-rw-r--r--src/video_core/texture_cache/slot_vector.h4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp9
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h11
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.h4
-rw-r--r--src/yuzu/CMakeLists.txt57
-rw-r--r--src/yuzu/applets/qt_controller.cpp1
-rw-r--r--src/yuzu/configuration/config.cpp1306
-rw-r--r--src/yuzu/configuration/config.h179
-rw-r--r--src/yuzu/configuration/configure_audio.cpp10
-rw-r--r--src/yuzu/configuration/configure_camera.cpp2
-rw-r--r--src/yuzu/configuration/configure_camera.h2
-rw-r--r--src/yuzu/configuration/configure_debug.cpp3
-rw-r--r--src/yuzu/configuration/configure_debug.ui86
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp1
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp36
-rw-r--r--src/yuzu/configuration/configure_input.cpp2
-rw-r--r--src/yuzu/configuration/configure_input.h2
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp8
-rw-r--r--src/yuzu/configuration/configure_input_advanced.h8
-rw-r--r--src/yuzu/configuration/configure_input_per_game.cpp6
-rw-r--r--src/yuzu/configuration/configure_input_per_game.h5
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp47
-rw-r--r--src/yuzu/configuration/configure_input_player.h2
-rw-r--r--src/yuzu/configuration/configure_input_player.ui389
-rw-r--r--src/yuzu/configuration/configure_input_player_widget.cpp45
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp7
-rw-r--r--src/yuzu/configuration/configure_per_game.h7
-rw-r--r--src/yuzu/configuration/configure_per_game_addons.cpp1
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp6
-rw-r--r--src/yuzu/configuration/configure_ringcon.cpp4
-rw-r--r--src/yuzu/configuration/configure_ringcon.h2
-rw-r--r--src/yuzu/configuration/configure_system.cpp1
-rw-r--r--src/yuzu/configuration/configure_tas.h2
-rw-r--r--src/yuzu/configuration/configure_touchscreen_advanced.cpp2
-rw-r--r--src/yuzu/configuration/configure_touchscreen_advanced.h2
-rw-r--r--src/yuzu/configuration/configure_ui.cpp7
-rw-r--r--src/yuzu/configuration/input_profiles.cpp10
-rw-r--r--src/yuzu/configuration/input_profiles.h4
-rw-r--r--src/yuzu/configuration/qt_config.cpp549
-rw-r--r--src/yuzu/configuration/qt_config.h55
-rw-r--r--src/yuzu/configuration/shared_translation.cpp518
-rw-r--r--src/yuzu/configuration/shared_translation.h43
-rw-r--r--src/yuzu/configuration/shared_widget.cpp4
-rw-r--r--src/yuzu/debugger/wait_tree.cpp6
-rw-r--r--src/yuzu/game_list.cpp13
-rw-r--r--src/yuzu/game_list_p.h8
-rw-r--r--src/yuzu/game_list_worker.cpp18
-rw-r--r--src/yuzu/hotkeys.cpp28
-rw-r--r--src/yuzu/hotkeys.h16
-rw-r--r--src/yuzu/main.cpp659
-rw-r--r--src/yuzu/main.h31
-rw-r--r--src/yuzu/main.ui22
-rw-r--r--src/yuzu/uisettings.cpp65
-rw-r--r--src/yuzu/uisettings.h93
-rw-r--r--src/yuzu/util/util.cpp15
-rw-r--r--src/yuzu/util/util.h3
-rw-r--r--src/yuzu/vk_device_info.cpp1
-rw-r--r--src/yuzu_cmd/CMakeLists.txt9
-rw-r--r--src/yuzu_cmd/config.cpp279
-rw-r--r--src/yuzu_cmd/config.h38
-rw-r--r--src/yuzu_cmd/default_ini.h553
-rw-r--r--src/yuzu_cmd/sdl_config.cpp257
-rw-r--r--src/yuzu_cmd/sdl_config.h49
-rw-r--r--src/yuzu_cmd/yuzu.cpp5
409 files changed, 36963 insertions, 27378 deletions
diff --git a/.ci/scripts/android/build.sh b/.ci/scripts/android/build.sh
index a5fd1ee18..d135af029 100755
--- a/.ci/scripts/android/build.sh
+++ b/.ci/scripts/android/build.sh
@@ -8,8 +8,17 @@ ccache -s
BUILD_FLAVOR=mainline
+if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
+ export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
+ base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
+fi
+
cd src/android
chmod +x ./gradlew
./gradlew "assemble${BUILD_FLAVOR}Release" "bundle${BUILD_FLAVOR}Release"
ccache -s
+
+if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
+ rm "${ANDROID_KEYSTORE_FILE}"
+fi
diff --git a/.ci/scripts/android/upload.sh b/.ci/scripts/android/upload.sh
index cfaeff328..5f8ca73c0 100755
--- a/.ci/scripts/android/upload.sh
+++ b/.ci/scripts/android/upload.sh
@@ -13,15 +13,3 @@ cp src/android/app/build/outputs/apk/"${BUILD_FLAVOR}/release/app-${BUILD_FLAVOR
"artifacts/${REV_NAME}.apk"
cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}Release"/"app-${BUILD_FLAVOR}-release.aab" \
"artifacts/${REV_NAME}.aab"
-
-if [ -n "${ANDROID_KEYSTORE_B64}" ]
-then
- echo "Signing apk..."
- base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > ks.jks
-
- apksigner sign --ks ks.jks \
- --ks-key-alias "${ANDROID_KEY_ALIAS}" \
- --ks-pass env:ANDROID_KEYSTORE_PASS "artifacts/${REV_NAME}.apk"
-else
- echo "No keystore specified, not signing the APK files."
-fi
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 000000000..109f2f45e
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,5 @@
+# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# CRLF -> LF
+90aa937593e53a5d5e070fb623b228578b0b225f
diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml
index 5893f860e..80aea4aa7 100644
--- a/.github/workflows/android-build.yml
+++ b/.github/workflows/android-build.yml
@@ -40,11 +40,11 @@ jobs:
sudo apt-get install -y ccache apksigner glslang-dev glslang-tools
- name: Build
run: ./.ci/scripts/android/build.sh
- - name: Copy and sign artifacts
env:
ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
+ - name: Copy artifacts
run: ./.ci/scripts/android/upload.sh
- name: Upload
uses: actions/upload-artifact@v3
diff --git a/.gitmodules b/.gitmodules
index b72a2ec8c..45dd0d259 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,9 +4,6 @@
[submodule "enet"]
path = externals/enet
url = https://github.com/lsalzman/enet.git
-[submodule "inih"]
- path = externals/inih/inih
- url = https://github.com/benhoyt/inih.git
[submodule "cubeb"]
path = externals/cubeb
url = https://github.com/mozilla/cubeb.git
@@ -61,3 +58,6 @@
[submodule "breakpad"]
path = externals/breakpad
url = https://github.com/yuzu-emu/breakpad.git
+[submodule "simpleini"]
+ path = externals/simpleini
+ url = https://github.com/brofield/simpleini.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c35e0946..ec7975b87 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -285,12 +285,12 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
find_package(Boost 1.79.0 REQUIRED context)
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
-find_package(inih 52 MODULE COMPONENTS INIReader)
find_package(LLVM 17.0.2 MODULE COMPONENTS Demangle)
find_package(lz4 REQUIRED)
find_package(nlohmann_json 3.8 REQUIRED)
find_package(Opus 1.3 MODULE)
find_package(RenderDoc MODULE)
+find_package(SimpleIni MODULE)
find_package(stb MODULE)
find_package(VulkanMemoryAllocator CONFIG)
find_package(ZLIB 1.2 REQUIRED)
diff --git a/CMakeModules/FindSimpleIni.cmake b/CMakeModules/FindSimpleIni.cmake
new file mode 100644
index 000000000..ce75d7690
--- /dev/null
+++ b/CMakeModules/FindSimpleIni.cmake
@@ -0,0 +1,19 @@
+# SPDX-FileCopyrightText: 2023 Alexandre Bouvier <contact@amb.tf>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+find_path(SimpleIni_INCLUDE_DIR SimpleIni.h)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SimpleIni
+ REQUIRED_VARS SimpleIni_INCLUDE_DIR
+)
+
+if (SimpleIni_FOUND AND NOT TARGET SimpleIni::SimpleIni)
+ add_library(SimpleIni::SimpleIni INTERFACE IMPORTED)
+ set_target_properties(SimpleIni::SimpleIni PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${SimpleIni_INCLUDE_DIR}"
+ )
+endif()
+
+mark_as_advanced(SimpleIni_INCLUDE_DIR)
diff --git a/CMakeModules/Findinih.cmake b/CMakeModules/Findinih.cmake
deleted file mode 100644
index 791befebd..000000000
--- a/CMakeModules/Findinih.cmake
+++ /dev/null
@@ -1,27 +0,0 @@
-# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf>
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-find_package(PkgConfig QUIET)
-pkg_search_module(INIH QUIET IMPORTED_TARGET inih)
-if (INIReader IN_LIST inih_FIND_COMPONENTS)
- pkg_search_module(INIREADER QUIET IMPORTED_TARGET INIReader)
- if (INIREADER_FOUND)
- set(inih_INIReader_FOUND TRUE)
- endif()
-endif()
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(inih
- REQUIRED_VARS INIH_LINK_LIBRARIES
- VERSION_VAR INIH_VERSION
- HANDLE_COMPONENTS
-)
-
-if (inih_FOUND AND NOT TARGET inih::inih)
- add_library(inih::inih ALIAS PkgConfig::INIH)
-endif()
-
-if (inih_FOUND AND inih_INIReader_FOUND AND NOT TARGET inih::INIReader)
- add_library(inih::INIReader ALIAS PkgConfig::INIREADER)
-endif()
diff --git a/dist/languages/.tx/config b/dist/languages/.tx/config
index 30e76b925..cca7b3d67 100644
--- a/dist/languages/.tx/config
+++ b/dist/languages/.tx/config
@@ -6,3 +6,8 @@ file_filter = <lang>.ts
source_file = en.ts
source_lang = en
type = QT
+
+[o:yuzu-emulator:p:yuzu:r:yuzu-android]
+file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml
+source_file = ../../src/android/app/src/main/res/values/strings.xml
+type = ANDROID
diff --git a/dist/languages/ar.ts b/dist/languages/ar.ts
index 89adc7e7b..3bd929ac9 100644
--- a/dist/languages/ar.ts
+++ b/dist/languages/ar.ts
@@ -4,7 +4,7 @@
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="14"/>
<source>About yuzu</source>
- <translation>عن يوزو</translation>
+ <translation>حول يوزو</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="72"/>
@@ -49,12 +49,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="23"/>
<source>Communicating with the server...</source>
- <translation>يتواصل مع الخادوم...</translation>
+ <translation>يتواصل مع الخادوم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="24"/>
<source>Cancel</source>
- <translation>الغِ</translation>
+ <translation>إلغاء</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="43"/>
@@ -69,12 +69,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="49"/>
<source>Configuration completed!</source>
- <translation>أتممت الضبط!</translation>
+ <translation>اكتمل الضبط</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="57"/>
<source>OK</source>
- <translation>حسنًا</translation>
+ <translation>نعم</translation>
</message>
</context>
<context>
@@ -87,12 +87,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
<source>Send Chat Message</source>
- <translation>أرسل رسالةً</translation>
+ <translation>إرسال رسالة دردشة</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
<source>Send Message</source>
- <translation>أرسل الرسالة</translation>
+ <translation>إرسال رسالة</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="181"/>
@@ -122,12 +122,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="330"/>
<source>%1 has been unbanned</source>
- <translation>رُفِع حظر %1</translation>
+ <translation>تم إلغاء حظر %1</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="446"/>
<source>View Profile</source>
- <translation>اعرض ملف المستخدم</translation>
+ <translation>عرض ملف المستخدم</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="459"/>
@@ -190,7 +190,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="47"/>
<source>Moderation...</source>
- <translation>الإشراف...</translation>
+ <translation>الإشراف</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="57"/>
@@ -208,7 +208,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
<source>Disconnected</source>
- <translation>ليس متصلًا</translation>
+ <translation>غير متصل</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
@@ -252,7 +252,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="107"/>
<source>No The game doesn&apos;t get past the &quot;Launching...&quot; screen</source>
- <translation>لا تشتغل، ولا تتعدى شاشة «يشغِّل...»</translation>
+ <translation>لا، اللعبة لا تتجاوز شاشة الإطلاق</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="124"/>
@@ -272,12 +272,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="176"/>
<source>Yes The game works without crashes</source>
- <translation>نعم، وتعمل دون أن تتعطل</translation>
+ <translation>نعم اللعبة تعمل بدون أعطال</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="183"/>
<source>No The game crashes or freezes during gameplay</source>
- <translation>لا، وتنهار أو تبقى معلَّقةً أثناء اللعب</translation>
+ <translation>لا، تتعطل اللعبة أو تتجمد أثناء اللعب</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="195"/>
@@ -302,12 +302,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="280"/>
<source>Major The game has major graphical errors</source>
- <translation>توجد أخطاء كبيرة توجد أخطاء رسمية كبيرة في اللعبة</translation>
+ <translation>توجد أخطاء كبيرة توجد أخطاء رسومية كبيرة في اللعبة</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="287"/>
<source>Minor The game has minor graphical errors</source>
- <translation>توجد أخطاء صغيرة توجد أخطاء رسمية صغيرة في اللعبة</translation>
+ <translation>توجد أخطاء صغيرة توجد أخطاء رسومية صغيرة في اللعبة</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="294"/>
@@ -342,7 +342,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="389"/>
<source>Thank you for your submission!</source>
- <translation>شكرا على مساهمتك!</translation>
+ <translation>شكرا على مساهمتك</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.cpp" line="121"/>
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>تلقائي (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>افتراضي (%1)</translation>
@@ -404,17 +404,17 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
<source>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</source>
- <translation type="unfinished"/>
+ <translation>حدد من أين تأتي صورة الكاميرا التي تمت محاكاتها. قد تكون كاميرا افتراضية أو كاميرا حقيقية.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="52"/>
<source>Camera Image Source:</source>
- <translation>مصدر صورة الكاميرا:</translation>
+ <translation>:مصدر صورة الكاميرا</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
<source>Input device:</source>
- <translation>جهاز الادخال:</translation>
+ <translation>:جهاز الادخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
@@ -424,7 +424,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="108"/>
<source>Resolution: 320*240</source>
- <translation>الدقة: 320*240</translation>
+ <translation>الدقة: 240*320</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
@@ -434,7 +434,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
<source>Restore Defaults</source>
- <translation>إعادة الأصلي</translation>
+ <translation>استعادة الافتراضي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.cpp" line="140"/>
@@ -462,7 +462,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="52"/>
<source>We recommend setting accuracy to &quot;Auto&quot;.</source>
- <translation>نحن نوصي بتتعين الدقة إلى &quot;تلقائي&quot;.</translation>
+ <translation>نوصي بضبط الدقة على &quot;تلقائي&quot;.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="65"/>
@@ -509,7 +509,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="48"/>
<source>Enable inline page tables</source>
- <translation type="unfinished"/>
+ <translation>تمكين جداول الصفحات المضمنة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="55"/>
@@ -521,7 +521,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="60"/>
<source>Enable block linking</source>
- <translation type="unfinished"/>
+ <translation>تمكين ربط الكتلة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="67"/>
@@ -557,7 +557,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="96"/>
<source>Enable context elimination</source>
- <translation type="unfinished"/>
+ <translation>تمكين حذف السياق</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="103"/>
@@ -581,7 +581,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="120"/>
<source>Enable miscellaneous optimizations</source>
- <translation type="unfinished"/>
+ <translation>تمكين التحسينات المتنوعة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="127"/>
@@ -594,7 +594,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="133"/>
<source>Enable misalignment check reduction</source>
- <translation type="unfinished"/>
+ <translation>تمكين تقليل التحقق من المحاذاة غير الصحيحة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="140"/>
@@ -643,17 +643,20 @@ This would ban both their forum username and their IP address.</source>
&lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by allowing invalid memory accesses to succeed.&lt;/div&gt;
&lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it reduces the overhead of all memory accesses and has no impact on programs that don't access invalid memory.&lt;/div&gt;
</source>
- <translation type="unfinished"/>
+ <translation>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;يعمل هذا التحسين على تسريع عمليات الوصول إلى الذاكرة عن طريق السماح بنجاح الوصول إلى الذاكرة غير الصالحة.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;يؤدي تمكينه إلى تقليل الحمل الزائد لجميع عمليات الوصول إلى الذاكرة وليس له أي تأثير على البرامج التي لا تصل إلى الذاكرة غير الصالحة.&lt;/div&gt;
+ </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="187"/>
<source>Enable fallbacks for invalid memory accesses</source>
- <translation type="unfinished"/>
+ <translation>تمكين الإجراءات الاحتياطية للوصول إلى الذاكرة غير الصالحة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="212"/>
<source>CPU settings are available only when game is not running.</source>
- <translation type="unfinished"/>
+ <translation>تتوفر إعدادات وحدة المعالجة المركزية فقط عندما لا تكون اللعبة قيد التشغيل.</translation>
</message>
</context>
<context>
@@ -671,7 +674,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="119"/>
<source>Port:</source>
- <translation>المنفذ:</translation>
+ <translation>:المنفذ</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="157"/>
@@ -706,7 +709,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="235"/>
<source>Homebrew</source>
- <translation type="unfinished"/>
+ <translation>البيرة المنزلية</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
@@ -786,7 +789,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="357"/>
<source>Enable Graphics Debugging</source>
- <translation type="unfinished"/>
+ <translation>تمكين تصحيح الرسومات</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="367"/>
@@ -816,7 +819,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="396"/>
<source>Perform Startup Vulkan Check</source>
- <translation type="unfinished"/>
+ <translation>Vulkan إجراء فحص بدء التشغيل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="403"/>
@@ -826,12 +829,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="410"/>
<source>Enable All Controller Types</source>
- <translation type="unfinished"/>
+ <translation>تمكين كافة أنواع اذرع التحكم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="417"/>
<source>Enable Auto-Stub**</source>
- <translation type="unfinished"/>
+ <translation>تمكين الإيقاف التلقائي**</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="424"/>
@@ -841,12 +844,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="431"/>
<source>Enable CPU Debugging</source>
- <translation type="unfinished"/>
+ <translation>تمكين تصحيح أخطاء وحدة المعالجة المركزية</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="438"/>
<source>Enable Debug Asserts</source>
- <translation type="unfinished"/>
+ <translation>تمكين تأكيدات التصحيح</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="464"/>
@@ -860,56 +863,36 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
- <translation type="unfinished"/>
+ <translation>تمكين خدمات التقارير المطولة**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
- <translation type="unfinished"/>
+ <translation>** سيتم إعادة ضبط هذا تلقائيًا عند إغلاق يوزو.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>إعادة التشغيل مطلوبة</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation type="unfinished"/>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation type="unfinished"/>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
<message>
<location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="14"/>
<source>Configure Debug Controller</source>
- <translation type="unfinished"/>
+ <translation>تهيئة تصحيح أخطاء ذراع التحكم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="40"/>
@@ -990,7 +973,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="68"/>
<source>GraphicsAdvanced</source>
- <translation type="unfinished"/>
+ <translation>الرسومات المتقدمة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="69"/>
@@ -1147,12 +1130,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="102"/>
<source>Select Dump Directory...</source>
- <translation type="unfinished"/>
+ <translation>حدد دليل التفريغ</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="105"/>
<source>Select Mod Load Directory...</source>
- <translation type="unfinished"/>
+ <translation>حدد دليل تحميل التعديل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="132"/>
@@ -1196,7 +1179,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_general.cpp" line="71"/>
<source>This reset all settings and remove all per-game configurations. This will not delete game directories, profiles, or input profiles. Proceed?</source>
- <translation type="unfinished"/>
+ <translation>يؤدي هذا إلى إعادة تعيين جميع الإعدادات وإزالة جميع التكوينات لكل لعبة. لن يؤدي هذا إلى حذف أدلة اللعبة أو الملفات الشخصية أو ملفات تعريف الإدخال. يتابع؟</translation>
</message>
</context>
<context>
@@ -1214,7 +1197,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="25"/>
<source>API Settings</source>
- <translation>إعدادات API</translation>
+ <translation>API إعدادات</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="58"/>
@@ -1224,7 +1207,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="103"/>
<source>Background Color:</source>
- <translation>لون الخلفية:</translation>
+ <translation>:لون الخلفية</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.cpp" line="259"/>
@@ -1301,7 +1284,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="52"/>
<source>Restore Defaults</source>
- <translation>إعادة الأصلي</translation>
+ <translation>استعادة الافتراضي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="100"/>
@@ -1316,12 +1299,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="100"/>
<source>Controller Hotkey</source>
- <translation type="unfinished"/>
+ <translation>مفتاح التحكم السريع</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>تسلسل أزرار متناقض مع الموجود</translation>
</message>
@@ -1342,27 +1325,37 @@ This would ban both their forum username and their IP address.</source>
<translation>غير صالح</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>إعدادات مفتاح الاختصار غير صالحة</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation>حدث خطأ. يرجى الإبلاغ عن هذه المشكلة على جيثب.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
- <translation>إعادة الأصلي</translation>
+ <translation>استعادة الافتراضي</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>مسح</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>سبق و تم تعيين تسلسل الأزرار الأصلي، مع: %1</translation>
</message>
@@ -1446,7 +1439,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="179"/>
<source>Vibration</source>
- <translation>إرتجاج</translation>
+ <translation>الاهتزاز</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="215"/>
@@ -1457,12 +1450,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="225"/>
<source>Motion</source>
- <translation>حركة</translation>
+ <translation>الحركة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="296"/>
<source>Controllers</source>
- <translation>أيادي التحكم</translation>
+ <translation>ذراع التحكم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="324"/>
@@ -1530,7 +1523,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="74"/>
<source>Joycon Colors</source>
- <translation>ألوان أيادي جويكون</translation>
+ <translation>ألوان جوي كون</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="125"/>
@@ -1559,7 +1552,7 @@ This would ban both their forum username and their IP address.</source>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2010"/>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2296"/>
<source>L Button</source>
- <translation type="unfinished"/>
+ <translation>L زر</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="295"/>
@@ -1583,7 +1576,7 @@ This would ban both their forum username and their IP address.</source>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2141"/>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2427"/>
<source>R Button</source>
- <translation type="unfinished"/>
+ <translation>R زر</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="411"/>
@@ -1648,7 +1641,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2595"/>
<source>Debug Controller</source>
- <translation>تصحيح أخطاء أداة التحكم</translation>
+ <translation>تصحيح أخطاء ذراع التحكم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2602"/>
@@ -1676,7 +1669,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2652"/>
<source>Emulate Analog with Keyboard Input</source>
- <translation type="unfinished"/>
+ <translation>محاكاة التناظرية مع إدخال لوحة المفاتيح</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2659"/>
@@ -1703,7 +1696,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2710"/>
<source>Enable direct JoyCon driver</source>
- <translation type="unfinished"/>
+ <translation>تمكين برنامج تشغيل جوي كون المباشر</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2726"/>
@@ -1741,52 +1734,52 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="28"/>
<source>Input Profiles</source>
- <translation type="unfinished"/>
+ <translation>ملفات تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="49"/>
<source>Player 1 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 1</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="84"/>
<source>Player 2 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 2</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="119"/>
<source>Player 3 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="154"/>
<source>Player 4 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 4</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="189"/>
<source>Player 5 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="224"/>
<source>Player 6 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 6</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="259"/>
<source>Player 7 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 7</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="294"/>
<source>Player 8 Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي للاعب 8</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.cpp" line="35"/>
<source>Use global input configuration</source>
- <translation type="unfinished"/>
+ <translation>استخدم تكوين الإدخال العالمي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.cpp" line="47"/>
@@ -1917,7 +1910,7 @@ This would ban both their forum username and their IP address.</source>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="802"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3030"/>
<source>Modifier Range: 0%</source>
- <translation type="unfinished"/>
+ <translation>0% :نطاق التعديل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="848"/>
@@ -1948,7 +1941,7 @@ This would ban both their forum username and their IP address.</source>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1456"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1495"/>
<source>Capture</source>
- <translation>تصوير</translation>
+ <translation>التقاط</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1526"/>
@@ -2038,7 +2031,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3085"/>
<source>Mouse panning</source>
- <translation type="unfinished"/>
+ <translation>تحريك الفأرة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3109"/>
@@ -2073,7 +2066,7 @@ This would ban both their forum username and their IP address.</source>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="395"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="667"/>
<source>Toggle button</source>
- <translation type="unfinished"/>
+ <translation>زر التبديل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="401"/>
@@ -2091,7 +2084,7 @@ This would ban both their forum username and their IP address.</source>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="425"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
<source>Set threshold</source>
- <translation type="unfinished"/>
+ <translation>تعيين الحد الأدنى</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="425"/>
@@ -2102,7 +2095,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="437"/>
<source>Toggle axis</source>
- <translation type="unfinished"/>
+ <translation>تبديل المحور</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="474"/>
@@ -2112,12 +2105,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="483"/>
<source>Calibrate sensor</source>
- <translation type="unfinished"/>
+ <translation>معايرة الاستشعار</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="523"/>
<source>Map Analog Stick</source>
- <translation type="unfinished"/>
+ <translation>خريطة عصا التناظرية</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="524"/>
@@ -2140,28 +2133,28 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="709"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1070"/>
<source>Modifier Range: %1%</source>
- <translation type="unfinished"/>
+ <translation>%1% :نطاق التعديل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="750"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1095"/>
<source>Pro Controller</source>
- <translation type="unfinished"/>
+ <translation>Pro Controller</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1099"/>
<source>Dual Joycons</source>
- <translation type="unfinished"/>
+ <translation>جوي كون ثنائي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1103"/>
<source>Left Joycon</source>
- <translation type="unfinished"/>
+ <translation>جوي كون يسار</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1107"/>
<source>Right Joycon</source>
- <translation type="unfinished"/>
+ <translation>جوي كون يمين</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1111"/>
@@ -2196,7 +2189,7 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1140"/>
<source>Sega Genesis</source>
- <translation type="unfinished"/>
+ <translation>Sega Genesis</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1344"/>
@@ -2211,12 +2204,12 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1348"/>
<source>Control Stick</source>
- <translation type="unfinished"/>
+ <translation>عصا التحكم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1349"/>
<source>C-Stick</source>
- <translation type="unfinished"/>
+ <translation>C-عصا</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1450"/>
@@ -2231,58 +2224,58 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1547"/>
<source>New Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي الجديد</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1547"/>
<source>Enter a profile name:</source>
- <translation type="unfinished"/>
+ <translation>:أدخل اسم الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1555"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1563"/>
<source>Create Input Profile</source>
- <translation type="unfinished"/>
+ <translation>إنشاء ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1556"/>
<source>The given profile name is not valid!</source>
- <translation type="unfinished"/>
+ <translation>اسم الملف الشخصي المحدد غير صالح!</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1564"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>&quot;%1&quot; فشل في إنشاء ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1584"/>
<source>Delete Input Profile</source>
- <translation type="unfinished"/>
+ <translation>حذف ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1585"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>&quot;%1&quot; فشل في مسح ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1607"/>
<source>Load Input Profile</source>
- <translation type="unfinished"/>
+ <translation>تحميل ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1608"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>&quot;%1&quot; فشل في تحميل ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1633"/>
<source>Save Input Profile</source>
- <translation type="unfinished"/>
+ <translation>حفظ ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1634"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>&quot;%1&quot; فشل في حفظ ملف تعريف الإدخال</translation>
</message>
</context>
<context>
@@ -2290,7 +2283,7 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_input_profile_dialog.ui" line="14"/>
<source>Create Input Profile</source>
- <translation type="unfinished"/>
+ <translation>إنشاء ملف تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_profile_dialog.ui" line="40"/>
@@ -2350,12 +2343,12 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="134"/>
<source>Server:</source>
- <translation type="unfinished"/>
+ <translation>:الخادم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="161"/>
<source>Port:</source>
- <translation>المنفذ:</translation>
+ <translation>:المنفذ</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="188"/>
@@ -2401,7 +2394,7 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="173"/>
<source>Port number has invalid characters</source>
- <translation type="unfinished"/>
+ <translation>يحتوي رقم المنفذ على أحرف غير صالحة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="177"/>
@@ -2411,7 +2404,7 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="181"/>
<source>IP address is not valid</source>
- <translation type="unfinished"/>
+ <translation>غير صالح IP عنوان</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="187"/>
@@ -2421,32 +2414,32 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="193"/>
<source>Unable to add more than 8 servers</source>
- <translation type="unfinished"/>
+ <translation>غير قادر على إضافة أكثر من 8 خوادم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="209"/>
<source>Testing</source>
- <translation type="unfinished"/>
+ <translation>اختبار</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="225"/>
<source>Configuring</source>
- <translation type="unfinished"/>
+ <translation>تكوين</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="256"/>
<source>Test Successful</source>
- <translation type="unfinished"/>
+ <translation>تم الاختبار بنجاح</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="257"/>
<source>Successfully received data from the server.</source>
- <translation type="unfinished"/>
+ <translation>تم استلام البيانات من الخادم بنجاح.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="259"/>
<source>Test Failed</source>
- <translation type="unfinished"/>
+ <translation>فشل الاختبار</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="260"/>
@@ -2464,12 +2457,12 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="6"/>
<source>Configure mouse panning</source>
- <translation type="unfinished"/>
+ <translation>تكوين تحريك الماوس</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="12"/>
<source>Enable mouse panning</source>
- <translation type="unfinished"/>
+ <translation>تمكين تحريك الماوس</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="15"/>
@@ -2508,12 +2501,12 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="88"/>
<source>Counteracts a game&apos;s built-in deadzone</source>
- <translation type="unfinished"/>
+ <translation>يتصدى للمنطقة الميتة المضمنة في اللعبة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="94"/>
<source>Deadzone</source>
- <translation type="unfinished"/>
+ <translation>المنطقة الميتة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="123"/>
@@ -2544,17 +2537,17 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.cpp" line="50"/>
<source>Emulated mouse is enabled. This is incompatible with mouse panning.</source>
- <translation type="unfinished"/>
+ <translation>تم تمكين الماوس الذي تمت محاكاته. وهذا غير متوافق مع تحريك الماوس.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.cpp" line="83"/>
<source>Emulated mouse is enabled</source>
- <translation type="unfinished"/>
+ <translation>تم تمكين الماوس الذي تمت محاكاته</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.cpp" line="84"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
- <translation type="unfinished"/>
+ <translation>الإدخال الحقيقي للماوس والتحريك بالماوس غير متوافقين. الرجاء تعطيل الماوس الذي تمت محاكاته في إعدادات الإدخال المتقدمة للسماح بتحريك الماوس.</translation>
</message>
</context>
<context>
@@ -2577,7 +2570,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_network.ui" line="34"/>
<source>Network Interface</source>
- <translation type="unfinished"/>
+ <translation>واجهة الشبكة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_network.cpp" line="15"/>
@@ -2595,7 +2588,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="34"/>
<source>Info</source>
- <translation type="unfinished"/>
+ <translation>معلومات</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="93"/>
@@ -2620,7 +2613,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="171"/>
<source>Version</source>
- <translation>النسخة</translation>
+ <translation>إصدار</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="178"/>
@@ -2660,7 +2653,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="72"/>
<source>Adv. Graphics</source>
- <translation type="unfinished"/>
+ <translation>الرسومات المتقدمة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="73"/>
@@ -2670,7 +2663,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="74"/>
<source>Input Profiles</source>
- <translation type="unfinished"/>
+ <translation>ملفات تعريف الإدخال</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="77"/>
@@ -2698,7 +2691,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game_addons.cpp" line="47"/>
<source>Version</source>
- <translation>النسخة</translation>
+ <translation>إصدار</translation>
</message>
</context>
<context>
@@ -2716,7 +2709,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="25"/>
<source>Profile Manager</source>
- <translation type="unfinished"/>
+ <translation>مدير الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="42"/>
@@ -2751,7 +2744,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="168"/>
<source>Profile management is available only when game is not running.</source>
- <translation type="unfinished"/>
+ <translation>إدارة الملف الشخصي متاحة فقط عندما لا تكون اللعبة قيد التشغيل.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="55"/>
@@ -2774,12 +2767,12 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="201"/>
<source>Enter a username for the new user:</source>
- <translation type="unfinished"/>
+ <translation>:أدخل اسم مستخدم للمستخدم الجديد</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="221"/>
<source>Enter a new username:</source>
- <translation type="unfinished"/>
+ <translation>:أدخل اسم مستخدم جديد</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="271"/>
@@ -2794,7 +2787,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="281"/>
<source>Error deleting image</source>
- <translation type="unfinished"/>
+ <translation>خطأ في حذف الصورة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="282"/>
@@ -2804,7 +2797,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="290"/>
<source>Error deleting file</source>
- <translation type="unfinished"/>
+ <translation>خطأ في حذف الملف</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="291"/>
@@ -2814,7 +2807,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="298"/>
<source>Error creating user image directory</source>
- <translation type="unfinished"/>
+ <translation>خطأ في إنشاء دليل صورة المستخدم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="299"/>
@@ -2824,7 +2817,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="304"/>
<source>Error copying user image</source>
- <translation type="unfinished"/>
+ <translation>حدث خطأ أثناء نسخ صورة المستخدم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="305"/>
@@ -2834,12 +2827,12 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="314"/>
<source>Error resizing user image</source>
- <translation type="unfinished"/>
+ <translation>خطأ في تغيير حجم صورة المستخدم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="315"/>
<source>Unable to resize image</source>
- <translation type="unfinished"/>
+ <translation>غير قادر على تغيير حجم الصورة</translation>
</message>
</context>
<context>
@@ -2847,7 +2840,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="332"/>
<source>Delete this user? All of the user&apos;s save data will be deleted.</source>
- <translation type="unfinished"/>
+ <translation>حذف هذا المستخدم؟ سيتم حذف جميع بيانات الحفظ الخاصة بالمستخدم.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="344"/>
@@ -2899,7 +2892,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="233"/>
<source>Direct Joycon Driver</source>
- <translation type="unfinished"/>
+ <translation>برنامج تشغيل جوي كون المباشر</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="293"/>
@@ -2921,12 +2914,12 @@ UUID: %2</source>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="314"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="282"/>
<source>Not connected</source>
- <translation type="unfinished"/>
+ <translation>غير متصل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="344"/>
<source>Restore Defaults</source>
- <translation>إعادة الأصلي</translation>
+ <translation>استعادة الافتراضي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="168"/>
@@ -2957,12 +2950,12 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="285"/>
<source>Direct Joycon driver is not enabled</source>
- <translation type="unfinished"/>
+ <translation>لم يتم تمكين برنامج تشغيل جوي كون المباشر</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="290"/>
<source>Configuring</source>
- <translation type="unfinished"/>
+ <translation>تكوين</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="302"/>
@@ -2977,7 +2970,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="309"/>
<source>The current mapped device is not connected</source>
- <translation type="unfinished"/>
+ <translation>الجهاز المعين الحالي غير متصل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="313"/>
@@ -3006,7 +2999,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_system.ui" line="62"/>
<source>Core</source>
- <translation type="unfinished"/>
+ <translation>نواة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_system.cpp" line="62"/>
@@ -3039,7 +3032,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
- <translation>الإعدادات</translation>
+ <translation>إعدادات</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
@@ -3054,7 +3047,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
- <translation type="unfinished"/>
+ <translation>إيقاف التنفيذ مؤقتا أثناء التحميل</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
@@ -3090,12 +3083,12 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="14"/>
<source>Configure Touchscreen Mappings</source>
- <translation type="unfinished"/>
+ <translation>تكوين تعيينات شاشة اللمس</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="22"/>
<source>Mapping:</source>
- <translation>تخطيط أزرار:</translation>
+ <translation>:تخطيط أزرار</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="48"/>
@@ -3110,13 +3103,14 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="74"/>
<source>Rename</source>
- <translation>تسمية</translation>
+ <translation>إعادة تسمية</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="92"/>
<source>Click the bottom area to add a point, then press a button to bind.
Drag points to change position, or double-click table cells to edit values.</source>
- <translation type="unfinished"/>
+ <translation>انقر على المنطقة السفلية لإضافة نقطة، ثم اضغط على زر للربط.
+اسحب النقاط لتغيير موضعها، أو انقر نقرًا مزدوجًا فوق خلايا الجدول لتحرير القيم.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="116"/>
@@ -3143,37 +3137,37 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="195"/>
<source>New Profile</source>
- <translation type="unfinished"/>
+ <translation>الملف الشخصي الجديد</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="195"/>
<source>Enter the name for the new profile.</source>
- <translation type="unfinished"/>
+ <translation>أدخل اسم الملف الشخصي الجديد.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="206"/>
<source>Delete Profile</source>
- <translation type="unfinished"/>
+ <translation>حذف الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="206"/>
<source>Delete profile %1?</source>
- <translation type="unfinished"/>
+ <translation>%1 حذف الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="219"/>
<source>Rename Profile</source>
- <translation type="unfinished"/>
+ <translation>إعادة تسمية الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="219"/>
<source>New name:</source>
- <translation type="unfinished"/>
+ <translation>:اسم جديد</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="231"/>
<source>[press key]</source>
- <translation type="unfinished"/>
+ <translation>[اضغط المفتاح]</translation>
</message>
</context>
<context>
@@ -3181,12 +3175,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="14"/>
<source>Configure Touchscreen</source>
- <translation type="unfinished"/>
+ <translation>تكوين شاشة اللمس</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="26"/>
<source>Warning: The settings in this page affect the inner workings of yuzu&apos;s emulated touchscreen. Changing them may result in undesirable behavior, such as the touchscreen partially or not working. You should only use this page if you know what you are doing.</source>
- <translation type="unfinished"/>
+ <translation>تحذير: تؤثر الإعدادات الموجودة في هذه الصفحة على الأعمال الداخلية لشاشة اللمس التي تمت محاكاتها في يوزو. قد يؤدي تغييرها إلى سلوك غير مرغوب فيه، مثل شاشة اللمس جزئيًا أو عدم عملها. يجب عليك استخدام هذه الصفحة فقط إذا كنت تعرف ما تفعله.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="52"/>
@@ -3206,12 +3200,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="98"/>
<source>Rotational Angle</source>
- <translation type="unfinished"/>
+ <translation>زاوية الدوران</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="132"/>
<source>Restore Defaults</source>
- <translation>إعادة الأصلي</translation>
+ <translation>استعادة الافتراضي</translation>
</message>
</context>
<context>
@@ -3299,17 +3293,17 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="31"/>
<source>Note: Changing language will apply your configuration.</source>
- <translation type="unfinished"/>
+ <translation>ملاحظة: سيؤدي تغيير اللغة إلى تطبيق التكوين الخاص بك.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="43"/>
<source>Interface language:</source>
- <translation>لغة الواجهة:</translation>
+ <translation>:لغة الواجهة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="57"/>
<source>Theme:</source>
- <translation>السمة:</translation>
+ <translation>:السمة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="74"/>
@@ -3319,7 +3313,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="82"/>
<source>Show Compatibility List</source>
- <translation>عرض قائمة التوافقية</translation>
+ <translation>عرض قائمة التوافق</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="89"/>
@@ -3337,67 +3331,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>عرض عمود أنواع الملف</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>إظهار عمود وقت التشغيل</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
- <translation>حجم أيقونة اللعبة:</translation>
+ <translation>:حجم أيقونة اللعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
- <translation>حجم أيقونة المجلد:</translation>
+ <translation>:حجم أيقونة المجلد</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
- <translation>نص السطر 1:</translation>
+ <translation>:نص السطر 1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
- <translation>نص السطر 2:</translation>
+ <translation>:نص السطر 2</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>لقطات الشاشة</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>اسأل أين أحفظ لقطات الشاشة (نظام التشغيل ويندوز فقط)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
- <translation>مسار لقطات الشاشة:</translation>
+ <translation>:مسار لقطات الشاشة</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
- <translation>الدقة:</translation>
+ <translation>:الدقة</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>أختر مسار لقطات الشاشة</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>تلقائي (%1 x %2, %3 x %4)</translation>
@@ -3408,17 +3407,17 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="14"/>
<source>Configure Vibration</source>
- <translation type="unfinished"/>
+ <translation>تكوين الاهتزاز</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="23"/>
<source>Press any controller button to vibrate the controller.</source>
- <translation type="unfinished"/>
+ <translation>اضغط على أي زر تحكم ليهتز جهاز التحكم.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="30"/>
<source>Vibration</source>
- <translation>إرتجاج</translation>
+ <translation>الاهتزاز</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="63"/>
@@ -3475,12 +3474,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="503"/>
<source>Settings</source>
- <translation>الإعدادات</translation>
+ <translation>إعدادات</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="509"/>
<source>Enable Accurate Vibration</source>
- <translation type="unfinished"/>
+ <translation>تمكين الاهتزاز الدقيق</translation>
</message>
</context>
<context>
@@ -3519,12 +3518,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="66"/>
<source>Token: </source>
- <translation>الرمز:</translation>
+ <translation>:الرمز</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="76"/>
<source>Username: </source>
- <translation>اسم المستخدم:</translation>
+ <translation>:اسم المستخدم</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="93"/>
@@ -3534,7 +3533,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
- <translation type="unfinished"/>
+ <translation>لا يمكن تغيير تكوين خدمة الويب إلا في حالة عدم استضافة غرفة عامة.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="128"/>
@@ -3554,7 +3553,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="150"/>
<source>Telemetry ID:</source>
- <translation>معرف القياس عن بعد:</translation>
+ <translation>:معرف القياس عن بعد</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="166"/>
@@ -3564,12 +3563,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="180"/>
<source>Discord Presence</source>
- <translation type="unfinished"/>
+ <translation>وجود ديسكورد</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="186"/>
<source>Show Current Game in your Discord Status</source>
- <translation type="unfinished"/>
+ <translation>إظهار اللعبة الحالية في حالة ديسكورد الخاصة بك</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="68"/>
@@ -3601,7 +3600,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="117"/>
<source>Token not verified</source>
- <translation type="unfinished"/>
+ <translation>لم يتم التحقق من الرمز المميز</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="118"/>
@@ -3612,35 +3611,35 @@ Drag points to change position, or double-click table cells to edit values.</sou
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
<source>Unverified, please click Verify before saving configuration</source>
<comment>Tooltip</comment>
- <translation type="unfinished"/>
+ <translation>لم يتم التحقق منه، الرجاء النقر فوق &quot;تحقق&quot; قبل حفظ التكوين</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
- <translation type="unfinished"/>
+ <translation>جاري التحقق</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
<source>Verified</source>
<comment>Tooltip</comment>
- <translation type="unfinished"/>
+ <translation>تم التحقق</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
<comment>Tooltip</comment>
- <translation type="unfinished"/>
+ <translation>فشل التحقق</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
<source>Verification failed</source>
- <translation type="unfinished"/>
+ <translation>فشل التحقق</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
- <translation type="unfinished"/>
+ <translation>فشل التحقق. تأكد من إدخال الرمز المميز الخاص بك بشكل صحيح، ومن أن اتصالك بالإنترنت يعمل.</translation>
</message>
</context>
<context>
@@ -3648,12 +3647,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/debugger/controller.cpp" line="20"/>
<source>Controller P1</source>
- <translation type="unfinished"/>
+ <translation>P1 ذراع التحكم</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/controller.cpp" line="58"/>
<source>&amp;Controller P1</source>
- <translation type="unfinished"/>
+ <translation>&amp;P1 ذراع التحكم</translation>
</message>
</context>
<context>
@@ -3661,12 +3660,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="14"/>
<source>Direct Connect</source>
- <translation type="unfinished"/>
+ <translation>اتصال مباشر</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="47"/>
<source>Server Address</source>
- <translation type="unfinished"/>
+ <translation>عنوان الخادم</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="54"/>
@@ -3686,7 +3685,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="97"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>الاسم المستعار</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="111"/>
@@ -3696,7 +3695,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="153"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>الاتصال</translation>
</message>
</context>
<context>
@@ -3704,970 +3703,1006 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="121"/>
<source>Connecting</source>
- <translation type="unfinished"/>
+ <translation>الاتصال</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="126"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>الاتصال</translation>
</message>
</context>
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>القياس عن بعد</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
- <translation type="unfinished"/>
+ <translation>معطل Vulkan تم اكتشاف تثبيت</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
- <translation type="unfinished"/>
+ <translation>تشغيل لعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
- <translation type="unfinished"/>
+ <translation>سرعة المحاكاة الحالية. تشير القيم الأعلى أو الأقل من 100% إلى أن المحاكاة تعمل بشكل أسرع أو أبطأ من سويتش.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
- <translation type="unfinished"/>
+ <translation>كم عدد الإطارات في الثانية التي تعرضها اللعبة حاليًا. سيختلف هذا من لعبة إلى أخرى ومن مشهد إلى آخر.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>إلغاء الكتم</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>كتم</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
- <translation type="unfinished"/>
+ <translation>إعادة ضبط مستوى الصوت</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;مسح الملفات الحديثة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
- <translation type="unfinished"/>
+ <translation>تم تمكين الماوس الذي تمت محاكاته</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
- <translation type="unfinished"/>
+ <translation>الإدخال الحقيقي للماوس والتحريك بالماوس غير متوافقين. الرجاء تعطيل الماوس الذي تمت محاكاته في إعدادات الإدخال المتقدمة للسماح بتحريك الماوس.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
- <translation>&amp;استمرار</translation>
+ <translation>&amp;استأنف</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;إيقاف مؤقت</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
- <translation type="unfinished"/>
+ <translation>تحذير من تنسيق اللعبة القديم</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
- <translation type="unfinished"/>
+ <translation>ROM خطأ أثناء تحميل </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
- <translation type="unfinished"/>
+ <translation>غير مدعوم ROM تنسيق.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
- <translation type="unfinished"/>
+ <translation>حدث خطأ غير معروف. يرجى الاطلاع على السجل لمزيد من التفاصيل.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
- <translation>(64-بت)</translation>
+ <translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
- <translation>(32-بت)</translation>
+ <translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
- <translation type="unfinished"/>
+ <translation>إغلاق البرامج</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
- <translation type="unfinished"/>
+ <translation>حفظ البيانات</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
- <translation type="unfinished"/>
+ <translation>%1 حدث خطأ أثناء فتح المجلد</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
- <translation type="unfinished"/>
+ <translation>المجلد غير موجود</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
- <translation type="unfinished"/>
+ <translation>فشل إنشاء دليل ذاكرة التخزين المؤقت للتظليل لهذا العنوان.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
- <translation type="unfinished"/>
+ <translation>خطأ في إزالة المحتويات</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
- <translation type="unfinished"/>
+ <translation>خطأ في إزالة التحديث</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
- <translation type="unfinished"/>
+ <translation>هل تريد إزالة محتويات اللعبة المثبتة؟</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
- <translation type="unfinished"/>
+ <translation>هل تريد إزالة تحديث اللعبة المثبت؟</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
- <translation type="unfinished"/>
+ <translation>للعبة المثبتة؟ DLC إزالة المحتوى القابل للتنزيل</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
- <translation type="unfinished"/>
+ <translation>إزالة الإدخال</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
- <translation type="unfinished"/>
+ <translation>تمت الإزالة بنجاح</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
- <translation type="unfinished"/>
+ <translation>تمت إزالة اللعبة الأساسية المثبتة بنجاح.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
- <translation type="unfinished"/>
+ <translation>تمت إزالة التحديث المثبت بنجاح.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
- <translation type="unfinished"/>
+ <translation>لا يوجد تحديث مثبت لهذا العنوان.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
- <translation type="unfinished"/>
+ <translation>مثبت لهذا العنوان DLC لا يوجد أي محتوى قابل للتنزيل.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
- <translation type="unfinished"/>
+ <translation>إزالة تكوين اللعبة المخصصة؟</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
- <translation type="unfinished"/>
+ <translation>إزالة الملف</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>إزالة بيانات وقت التشغيل</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>إعادة تعيين وقت اللعب؟</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
- <translation type="unfinished"/>
+ <translation>حدث خطأ أثناء إزالة التكوين المخصص</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
- <translation type="unfinished"/>
+ <translation>لا يوجد تكوين مخصص لهذا العنوان.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
- <translation type="unfinished"/>
+ <translation>تمت إزالة تكوين اللعبة المخصص بنجاح.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
- <translation type="unfinished"/>
+ <translation>فشل إزالة تكوين اللعبة المخصص.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
- <translation type="unfinished"/>
+ <translation>كامل</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>إلغاء</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>أكتملت العملية بنجاح</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
- <translation type="unfinished"/>
+ <translation>لا يمكن إجراء التحقق من سلامة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
- <translation type="unfinished"/>
+ <translation>لم يتم التحقق من صحة محتويات الملف.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
- <translation type="unfinished"/>
+ <translation>فشل التحقق من سلامة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
- <translation type="unfinished"/>
+ <translation>قد تكون محتويات الملف تالفة.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
- <translation type="unfinished"/>
+ <translation>التحقق من سلامة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
- <translation type="unfinished"/>
+ <translation>نجح التحقق من سلامة!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>إنشاء إختصار</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
- <translation type="unfinished"/>
+ <translation>إنشاء أيقونة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>بدء %1 بمحاكي يوزو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
- <translation type="unfinished"/>
+ <translation>حدد الدليل</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>الخصائص</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
- <translation type="unfinished"/>
+ <translation>تعذر تحميل خصائص اللعبة.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>تشغيل المِلَفّ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
- <translation type="unfinished"/>
+ <translation>تم تحديد دليل غير صالح</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
- <translation type="unfinished"/>
+ <translation>تثبيت الملفات</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
- <translation type="unfinished"/>
+ <translation>تطبيق النظام</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
- <translation type="unfinished"/>
+ <translation>أرشيف النظام</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
- <translation type="unfinished"/>
+ <translation>تحديث تطبيق النظام</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>اللعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
- <translation type="unfinished"/>
+ <translation>تحديث اللعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
- <translation type="unfinished"/>
+ <translation>فشل فى التثبيت</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>لم يتم العثور على الملف</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>موافق</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>حساب يوزو مفقود</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>خطأ في فتح URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
- <translation type="unfinished"/>
+ <translation>تم اكتشاف تكوين غير صالح</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>أميبو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>أميبو اللعبة الحالية تمت إزالته</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>خطأ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>اللعبة الحالية لا تبحث عن أميبو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>تحميل أميبو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>خطأ أثناء تحميل بيانات أميبو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
- <translation type="unfinished"/>
+ <translation>الملف المحدد قيد الاستخدام بالفعل</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
- <translation type="unfinished"/>
+ <translation>حدث خطأ غير معروف</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>التطبيق الصغير للألبوم</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>لقطة شاشة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;إيقاف التشغيل</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
- <translation>&amp;ابدأ</translation>
+ <translation>&amp;بدء</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>&amp;إيقاف التسجيل</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>&amp;تسجيل</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
- <translation type="unfinished"/>
+ <translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
- <translation type="unfinished"/>
+ <translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4678,90 +4713,92 @@ This will delete your autogenerated key files and re-run the key derivation modu
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
- <translation type="unfinished"/>
+ <translation>فشل فك تشفير أرشيف النظام</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
- <translation>هل انت متاكد انك تريد اغلاق يوزو?</translation>
+ <translation>هل أنت متأكد أنك تريد إغلاق يوزو؟</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>يوزو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>هل أنت متأكد أنك تريد إيقاف المحاكاة؟ ستيم فقد البيانات التي لم تتم حفظه</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
- <translation type="unfinished"/>
+ <translation>لقد طلب التطبيق قيد التشغيل حاليًا من يوزو عدم الخروج.
+
+هل ترغب في تجاوز هذا والخروج على أية حال؟</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="71"/>
@@ -4771,37 +4808,37 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="72"/>
<source>FXAA</source>
- <translation type="unfinished"/>
+ <translation>FXAA</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>SMAA</source>
- <translation type="unfinished"/>
+ <translation>SMAA</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Nearest</source>
- <translation type="unfinished"/>
+ <translation>Nearest</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Bilinear</source>
- <translation type="unfinished"/>
+ <translation>Bilinear</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Bicubic</source>
- <translation type="unfinished"/>
+ <translation>Bicubic</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Gaussian</source>
- <translation type="unfinished"/>
+ <translation>Gaussian</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>ScaleForce</source>
- <translation type="unfinished"/>
+ <translation>ScaleForce</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
@@ -4831,32 +4868,32 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="101"/>
<source>Vulkan</source>
- <translation type="unfinished"/>
+ <translation>Vulkan</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="102"/>
<source>OpenGL</source>
- <translation type="unfinished"/>
+ <translation>OpenGL</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="103"/>
<source>Null</source>
- <translation type="unfinished"/>
+ <translation>قيمه خاليه</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="107"/>
<source>GLSL</source>
- <translation type="unfinished"/>
+ <translation>GLSL</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="108"/>
<source>GLASM</source>
- <translation type="unfinished"/>
+ <translation>GLASM</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="109"/>
<source>SPIRV</source>
- <translation type="unfinished"/>
+ <translation>SPIRV</translation>
</message>
</context>
<context>
@@ -4907,251 +4944,261 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>مفضلة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>بدء اللعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>بدء اللعبة بدون الإعدادات المخصصة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>فتح موقع بيانات الحفظ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>فتح موقع بيانات التعديلات</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>ازالة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>ازالة التحديث المثبت</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>ازل جميع المحتويات المثبتها</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
- <translation type="unfinished"/>
+ <translation>إزالة التكوين المخصص</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>إزالة بيانات وقت التشغيل</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>قم بإزالة كافة المحتويات المثبتة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
- <translation type="unfinished"/>
+ <translation> التحقق من سلامة </translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>إنشاء إختصار</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>إضافة إلى سطح المكتب</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>إضافة إلى قائمة التطبيقات</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>الخصائص</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>مسح الملفات الداخلية</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
- <translation type="unfinished"/>
+ <translation>إزالة دليل اللعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ نقل للأعلى</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ نقل للأسفل</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>فتح موقع الدليل</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>مسح</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>الاسم</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>التوافق</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>الإضافات</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>نوع الملف</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>الحجم</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>وقت اللعب</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
- <translation type="unfinished"/>
+ <translation>في اللعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
- <translation type="unfinished"/>
+ <translation>تبدأ اللعبة، لكن الأعطال أو الأخطاء الرئيسية تمنعها من الاكتمال.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
- <translation>متقن</translation>
+ <translation>مثالي</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
- <translation type="unfinished"/>
+ <translation>يمكن لعب اللعبة بدون مشاكل.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>قابل للعب</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
- <translation type="unfinished"/>
+ <translation>تحتوي وظائف اللعبة على بعض الأخطاء الرسومية أو الصوتية البسيطة ويمكن تشغيلها من البداية إلى النهاية.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
- <translation>مقدمة أو قوائم</translation>
+ <translation>مقدمة/القائمة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
- <translation type="unfinished"/>
+ <translation>يتم تحميل اللعبة، ولكنها غير قادرة على التقدم بعد شاشة البدء.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>لا تفتح</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
- <translation type="unfinished"/>
+ <translation>تعطل اللعبة عند محاولة بدء التشغيل.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>لم تختبر</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
- <translation type="unfinished"/>
+ <translation>اللعبة لم يتم اختبارها بعد.</translation>
</message>
</context>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
- <translation type="unfinished"/>
+ <translation>انقر نقرًا مزدوجًا لإضافة مجلد جديد إلى قائمة الألعاب</translation>
</message>
</context>
<context>
@@ -5162,14 +5209,14 @@ Would you like to bypass this and exit anyway?</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
- <translation type="unfinished"/>
+ <translation>:تصفيه</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
- <translation type="unfinished"/>
+ <translation>أدخل النمط للتصفية</translation>
</message>
</context>
<context>
@@ -5177,7 +5224,7 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="14"/>
<source>Create Room</source>
- <translation type="unfinished"/>
+ <translation>إنشاء غرفة</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="37"/>
@@ -5202,7 +5249,7 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="101"/>
<source>(Leave blank for open game)</source>
- <translation type="unfinished"/>
+ <translation>(اتركه فارغا للعبة مفتوحة)</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="118"/>
@@ -5222,7 +5269,7 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
<source>Load Previous Ban List</source>
- <translation type="unfinished"/>
+ <translation>تحميل قائمة الحظر السابقة</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="184"/>
@@ -5232,12 +5279,12 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="189"/>
<source>Unlisted</source>
- <translation type="unfinished"/>
+ <translation>غير مدرج</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
<source>Host Room</source>
- <translation type="unfinished"/>
+ <translation>غرفة المضيفة</translation>
</message>
</context>
<context>
@@ -5259,7 +5306,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="118"/>
<source>Audio Mute/Unmute</source>
- <translation type="unfinished"/>
+ <translation>كتم الصوت/إلغاء كتم الصوت</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="118"/>
@@ -5284,18 +5331,19 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
- <translation type="unfinished"/>
+ <translation>النافذة الرئيسية</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="119"/>
<source>Audio Volume Down</source>
- <translation type="unfinished"/>
+ <translation>خفض مستوى الصوت</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="120"/>
<source>Audio Volume Up</source>
- <translation type="unfinished"/>
+ <translation>رفع مستوى الصوت</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="121"/>
@@ -5310,7 +5358,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="123"/>
<source>Change Docked Mode</source>
- <translation type="unfinished"/>
+ <translation>تغيير وضع الإرساء</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="124"/>
@@ -5320,7 +5368,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="125"/>
<source>Continue/Pause Emulation</source>
- <translation type="unfinished"/>
+ <translation>متابعة/إيقاف مؤقت للمحاكاة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="126"/>
@@ -5340,7 +5388,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="129"/>
<source>Load File</source>
- <translation>تشغيل المِلَفّ</translation>
+ <translation>تحميل الملف</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="130"/>
@@ -5350,12 +5398,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="131"/>
<source>Restart Emulation</source>
- <translation type="unfinished"/>
+ <translation>إعادة تشغيل المحاكاة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="132"/>
<source>Stop Emulation</source>
- <translation type="unfinished"/>
+ <translation>إيقاف المحاكاة</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="133"/>
@@ -5380,7 +5428,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<source>Toggle Framerate Limit</source>
- <translation type="unfinished"/>
+ <translation>تبديل حد معدل الإطارات</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
@@ -5389,9 +5437,14 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
- <source>Toggle Status Bar</source>
+ <source>Toggle Renderdoc Capture</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
+ <source>Toggle Status Bar</source>
+ <translation>تبديل شريط الحالة</translation>
+ </message>
</context>
<context>
<name>InstallDialog</name>
@@ -5403,7 +5456,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/install_dialog.cpp" line="32"/>
<source>Installing an Update or DLC will overwrite the previously installed one.</source>
- <translation type="unfinished"/>
+ <translation>إلى استبدال التحديث المثبت مسبقًا DLC سيؤدي تثبيت التحديث أو المحتوى القابل للتنزيل</translation>
</message>
<message>
<location filename="../../src/yuzu/install_dialog.cpp" line="36"/>
@@ -5422,7 +5475,8 @@ Debug Message: </source>
<location filename="../../src/yuzu/util/limitable_input_dialog.cpp" line="59"/>
<source>The text can't contain any of the following characters:
%1</source>
- <translation type="unfinished"/>
+ <translation>لا يمكن أن يحتوي النص على أي من الأحرف التالية:
+%1</translation>
</message>
</context>
<context>
@@ -5430,17 +5484,17 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/loading_screen.ui" line="84"/>
<source>Loading Shaders 387 / 1628</source>
- <translation type="unfinished"/>
+ <translation>تحميل التظليل 1628 / 387</translation>
</message>
<message>
<location filename="../../src/yuzu/loading_screen.ui" line="121"/>
<source>Loading Shaders %v out of %m</source>
- <translation type="unfinished"/>
+ <translation>%m من %v جاري تحميل التظليل</translation>
</message>
<message>
<location filename="../../src/yuzu/loading_screen.ui" line="135"/>
<source>Estimated Time 5m 4s</source>
- <translation type="unfinished"/>
+ <translation> 5m 4s الوقت المقدر </translation>
</message>
<message>
<location filename="../../src/yuzu/loading_screen.cpp" line="83"/>
@@ -5450,7 +5504,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/loading_screen.cpp" line="84"/>
<source>Loading Shaders %1 / %2</source>
- <translation type="unfinished"/>
+ <translation>%1 / %2 جاري تحميل التظليل</translation>
</message>
<message>
<location filename="../../src/yuzu/loading_screen.cpp" line="85"/>
@@ -5460,7 +5514,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/loading_screen.cpp" line="170"/>
<source>Estimated Time %1</source>
- <translation type="unfinished"/>
+ <translation>%1 الوقت المقدر</translation>
</message>
</context>
<context>
@@ -5468,18 +5522,18 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="14"/>
<source>Public Room Browser</source>
- <translation type="unfinished"/>
+ <translation>متصفح الغرفة العامة</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="32"/>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="39"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>الاسم المستعار</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="59"/>
<source>Filters</source>
- <translation type="unfinished"/>
+ <translation>المرشحات</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="66"/>
@@ -5514,7 +5568,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.cpp" line="114"/>
<source>Password:</source>
- <translation>كلمة المرور:</translation>
+ <translation>:كلمة المرور</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.cpp" line="217"/>
@@ -5544,7 +5598,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.cpp" line="284"/>
<source>Refresh List</source>
- <translation>إنعاش القائمة</translation>
+ <translation>تحديث القائمة</translation>
</message>
</context>
<context>
@@ -5577,7 +5631,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="81"/>
<source>&amp;Reset Window Size</source>
- <translation>&amp;إعادة تعيين حجم الشاشة</translation>
+ <translation>&amp;إعادة ضبط حجم النافذة</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="86"/>
@@ -5587,32 +5641,32 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="91"/>
<source>Reset Window Size to &amp;720p</source>
- <translation>اعادة تعيين حجم النافذة إلى &amp;720p</translation>
+ <translation>720p إعادة تعيين حجم النافذة إلى</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="94"/>
<source>Reset Window Size to 720p</source>
- <translation>اعادة تعيين حجم النافذة إلى 720p</translation>
+ <translation>720p إعادة تعيين حجم النافذة إلى</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="99"/>
<source>Reset Window Size to &amp;900p</source>
- <translation>اعادة تعيين حجم النافذة إلى &amp;900p</translation>
+ <translation>900p إعادة تعيين حجم النافذة إلى</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="102"/>
<source>Reset Window Size to 900p</source>
- <translation>اعادة تعيين حجم النافذة إلى 900p</translation>
+ <translation>900p إعادة تعيين حجم النافذة إلى</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="107"/>
<source>Reset Window Size to &amp;1080p</source>
- <translation>اعادة تعيين حجم النافذة إلى &amp;1080p</translation>
+ <translation>1080p إعادة تعيين حجم النافذة إلى</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="110"/>
<source>Reset Window Size to 1080p</source>
- <translation>اعادة تعيين حجم النافذة إلى 1080p</translation>
+ <translation>1080p إعادة تعيين حجم النافذة إلى</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="127"/>
@@ -5626,186 +5680,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>أميبو</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;مساعدة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
- <translation>&amp;تثبيت الملفات الى الذاكرة الداخلية...</translation>
+ <translation>&amp;NAND تثبيت الملفات على</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
- <translation>&amp;تحميل ملف...</translation>
+ <translation>&amp;تحميل ملف</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
- <translation>تحميل &amp;مجلد...</translation>
+ <translation>تحميل &amp;مجلد</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>&amp;خروج</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;إيقاف مؤقت</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;إيقاف</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
- <translation>&amp;إعادة تهيئة المفاتيح...</translation>
+ <translation>&amp;إعادة تهيئة المفاتيح</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>التحقق من المحتويات المثبتة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
- <translation>&amp;عن يوزو</translation>
+ <translation>&amp;حول يوزو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
- <translation>وضع &amp;الشاشة الواحدة</translation>
+ <translation>وضع النافذة الواحدة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
- <translation>&amp;أعدادات...</translation>
+ <translation>&amp;أعدادات</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
- <translation>عرض &amp;شريط المرشح</translation>
+ <translation>عرض &amp;شريط التصفية</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>عرض &amp;شريط الحالة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>عرض شريط الحالة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;استعراض ردهة الألعاب العامة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;إنشاء غرفة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;مغادرة الغرفة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;اتصال مباشر مع غرفة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;عرض الغرفة الحالية</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
- <translation>&amp;ملئ الشاشة</translation>
+ <translation>&amp;ملء الشاشة</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;إعادة التشغيل</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
- <translation>تحميل/إزالة &amp;أميبو...</translation>
+ <translation>تحميل/إزالة &amp;أميبو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
- <translation>&amp;تقرير توافقية</translation>
+ <translation>&amp;تقرير التوافق</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>فتح صفحة &amp;التعديلات</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
- <translation>فتح دليل &amp;البداية السريعة</translation>
+ <translation>فتح دليل التشغيل السريع</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
- <translation>&amp;الاسئلة الاكثر شيوعا</translation>
+ <translation>&amp;التعليمات</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>فتح مجلد &amp;يوزو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
- <translation>&amp;لقط الشاشة</translation>
+ <translation>&amp;التقاط لقطة للشاشة</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>افتح الألبوم</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>&amp;تعيين الاسم المستعار والمالك</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>حذف بيانات اللعبة</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>&amp;استعادة أميبو</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>&amp;تنسيق أميبو</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
- <translation type="unfinished"/>
+ <translation>Mii فتح محرر</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>إعدادات &amp;اللعبة الحالية</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
- <translation>&amp;ابدأ</translation>
+ <translation>&amp;بدء</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;إعادة تعيين</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>&amp;تسجيل</translation>
</message>
@@ -5854,7 +5938,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="83"/>
<source>Forum Username</source>
- <translation type="unfinished"/>
+ <translation>اسم المستخدم في المنتدى</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="88"/>
@@ -5903,7 +5987,8 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="208"/>
<source>Failed to update the room information. Please check your Internet connection and try hosting the room again.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>فشل في تحديث معلومات الغرفة. يرجى التحقق من اتصالك بالإنترنت ومحاولة استضافة الغرفة مرة أخرى.
+رسالة التصحيح:</translation>
</message>
</context>
<context>
@@ -5936,37 +6021,37 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
<source>You must choose a Preferred Game to host a room. If you do not have any games in your game list yet, add a game folder by clicking on the plus icon in the game list.</source>
- <translation type="unfinished"/>
+ <translation>يجب عليك اختيار لعبة مفضلة لاستضافة غرفة. إذا لم يكن لديك أي ألعاب في قائمة الألعاب الخاصة بك حتى الآن، قم بإضافة مجلد الألعاب من خلال النقر على أيقونة الزائد في قائمة الألعاب.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
<source>Unable to find an internet connection. Check your internet settings.</source>
- <translation type="unfinished"/>
+ <translation>غير قادر على العثور على اتصال بالإنترنت. تحقق من إعدادات الإنترنت لديك.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="26"/>
<source>Unable to connect to the host. Verify that the connection settings are correct. If you still cannot connect, contact the room host and verify that the host is properly configured with the external port forwarded.</source>
- <translation type="unfinished"/>
+ <translation>غير قادر على الاتصال بالمضيف. تأكد من صحة إعدادات الاتصال. إذا كنت لا تزال غير قادر على الاتصال، فاتصل بمضيف الغرفة وتأكد من تكوين المضيف بشكل صحيح مع إعادة توجيه المنفذ الخارجي.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="30"/>
<source>Unable to connect to the room because it is already full.</source>
- <translation type="unfinished"/>
+ <translation>غير قادر على الاتصال بالغرفة لأنها ممتلئة بالفعل.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="32"/>
<source>Creating a room failed. Please retry. Restarting yuzu might be necessary.</source>
- <translation type="unfinished"/>
+ <translation>فشل إنشاء الغرفة. الرجاء اعادة المحاولة. قد تكون إعادة تشغيل يوزو ضرورية.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
<source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
- <translation type="unfinished"/>
+ <translation>لقد قام مضيف الغرفة بحظرك. تحدث مع المضيف لإلغاء الحظر عليك أو تجربة غرفة مختلفة.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
<source>Version mismatch! Please update to the latest version of yuzu. If the problem persists, contact the room host and ask them to update the server.</source>
- <translation type="unfinished"/>
+ <translation>عدم تطابق إصدار! يرجى التحديث إلى أحدث إصدار من يوزو. إذا استمرت المشكلة، فاتصل بمضيف الغرفة واطلب منه تحديث الخادم.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
@@ -6009,18 +6094,20 @@ They may have left the room.</source>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="52"/>
<source>No valid network interface is selected.
Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
- <translation type="unfinished"/>
+ <translation>لم يتم تحديد واجهة شبكة صالحة.
+يرجى الانتقال إلى التكوين -&gt; النظام -&gt; الشبكة وتحديد الاختيار.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
<source>Game already running</source>
- <translation>اللعبة تشتغل مسبقا</translation>
+ <translation>اللعبة قيد التشغيل بالفعل</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
<source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
Proceed anyway?</source>
- <translation type="unfinished"/>
+ <translation>لا يُنصح بالانضمام إلى غرفة عندما تكون اللعبة قيد التشغيل بالفعل وقد يؤدي ذلك إلى عدم عمل ميزة الغرفة بشكل صحيح.
+المتابعة على أية حال؟</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
@@ -6110,27 +6197,27 @@ p, li { white-space: pre-wrap; }
<translation>لا يلعب أي لعبة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>عناوين مثبته على بطاقة الذاكرة</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>عناوين مثبته على الذاكرة الداخلية</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>عناوين النظام</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>اضافة دليل ألعاب جديد</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>المفضلة</translation>
</message>
@@ -6272,7 +6359,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="69"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="92"/>
<source>Start</source>
- <translation>ابدأ</translation>
+ <translation>Start</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="71"/>
@@ -6602,17 +6689,17 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="232"/>
<source>The following amiibo data will be formatted:</source>
- <translation>بيانات أمبيو التالية سيتم تهيئتها:</translation>
+ <translation>:بيانات أمبيو التالية سيتم تهيئتها</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="235"/>
<source>The following game data will removed:</source>
- <translation>بيانات الألعاب التالية سيتم إزالتها:</translation>
+ <translation>:بيانات الألعاب التالية سيتم إزالتها</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="238"/>
<source>Set nickname and owner:</source>
- <translation type="unfinished"/>
+ <translation>تعيين الاسم المستعار والمالك</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="241"/>
@@ -6630,12 +6717,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="129"/>
<source>Supported Controller Types:</source>
- <translation>أنواع أداوت التحكم المدعومة:</translation>
+ <translation>:أنواع ذراع التحكم المدعومة</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="282"/>
<source>Players:</source>
- <translation>اللاعبين:</translation>
+ <translation>:اللاعبين</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="300"/>
@@ -6645,7 +6732,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="418"/>
<source>P4</source>
- <translation type="unfinished"/>
+ <translation>P4</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="514"/>
@@ -6656,9 +6743,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
- <translation type="unfinished"/>
+ <translation>Pro Controller</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="519"/>
@@ -6669,9 +6756,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
- <translation type="unfinished"/>
+ <translation>جوي كون ثنائي</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="524"/>
@@ -6682,9 +6769,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
- <translation type="unfinished"/>
+ <translation>جوي كون يسار</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="529"/>
@@ -6695,9 +6782,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
- <translation type="unfinished"/>
+ <translation>جوي كون يمين</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="538"/>
@@ -6709,49 +6796,49 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1881"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2078"/>
<source>Use Current Config</source>
- <translation type="unfinished"/>
+ <translation>استخدم التكوين الحالي</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="615"/>
<source>P2</source>
- <translation type="unfinished"/>
+ <translation>P2</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="812"/>
<source>P1</source>
- <translation type="unfinished"/>
+ <translation>P1</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>محمول</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1126"/>
<source>P3</source>
- <translation type="unfinished"/>
+ <translation>P3</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1363"/>
<source>P7</source>
- <translation type="unfinished"/>
+ <translation>P7</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1560"/>
<source>P8</source>
- <translation type="unfinished"/>
+ <translation>P8</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1757"/>
<source>P5</source>
- <translation type="unfinished"/>
+ <translation>P5</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1958"/>
<source>P6</source>
- <translation type="unfinished"/>
+ <translation>P6</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2272"/>
@@ -6766,7 +6853,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2313"/>
<source>Vibration</source>
- <translation>إرتجاج</translation>
+ <translation>الاهتزاز</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2349"/>
@@ -6792,7 +6879,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2467"/>
<source>Controllers</source>
- <translation>أيادي التحكم</translation>
+ <translation>ذراع التحكم</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2481"/>
@@ -6840,34 +6927,39 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>لا توجد اذرع تحكم كافية</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
- <translation>أداة تحكم GameCube</translation>
+ <translation>ذراع تحكم GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
- <translation>أداة تحكم NES</translation>
+ <translation>ذراع تحكم NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
- <translation>أداة تحكم SNES</translation>
+ <translation>ذراع تحكم SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
- <translation>أداة تحكم N64</translation>
+ <translation>ذراع تحكم N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
- <translation type="unfinished"/>
+ <translation>Sega Genesis</translation>
</message>
</context>
<context>
@@ -6883,7 +6975,8 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_error.cpp" line="31"/>
<source>An error has occurred.
Please try again or contact the developer of the software.</source>
- <translation type="unfinished"/>
+ <translation>حدث خطأ.
+يرجى المحاولة مرة أخرى أو الاتصال بمطور البرنامج.</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_error.cpp" line="44"/>
@@ -6898,7 +6991,11 @@ Please try again or contact the developer of the software.</source>
%1
%2</source>
- <translation type="unfinished"/>
+ <translation>حدث خطأ.
+
+%1
+
+%2</translation>
</message>
</context>
<context>
@@ -6919,73 +7016,73 @@ Please try again or contact the developer of the software.</source>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="167"/>
<source>Profile Creator</source>
- <translation type="unfinished"/>
+ <translation>منشئ الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="170"/>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="188"/>
<source>Profile Selector</source>
- <translation type="unfinished"/>
+ <translation>محدد الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="173"/>
<source>Profile Icon Editor</source>
- <translation type="unfinished"/>
+ <translation>محرر أيقونة الملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="176"/>
<source>Profile Nickname Editor</source>
- <translation type="unfinished"/>
+ <translation>محرر الاسم المستعار للملف الشخصي</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="198"/>
<source>Who will receive the points?</source>
- <translation type="unfinished"/>
+ <translation>من سيحصل على النقاط؟</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="201"/>
<source>Who is using Nintendo eShop?</source>
- <translation type="unfinished"/>
+ <translation> ؟Nintendo eShop من يستخدم</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="204"/>
<source>Who is making this purchase?</source>
- <translation type="unfinished"/>
+ <translation>من يقوم بهذا الشراء؟</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="207"/>
<source>Who is posting?</source>
- <translation type="unfinished"/>
+ <translation>من ينشر؟</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="210"/>
<source>Select a user to link to a Nintendo Account.</source>
- <translation type="unfinished"/>
+ <translation>Nintendo حدد مستخدمًا لربطه بحساب</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="213"/>
<source>Change settings for which user?</source>
- <translation type="unfinished"/>
+ <translation>تغيير الإعدادات لأي مستخدم؟</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="216"/>
<source>Format data for which user?</source>
- <translation type="unfinished"/>
+ <translation>تنسيق البيانات لأي مستخدم؟</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="219"/>
<source>Which user will be transferred to another console?</source>
- <translation type="unfinished"/>
+ <translation>من هو المستخدم الذي سيتم نقله إلى وحدة تحكم أخرى؟</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="222"/>
<source>Send save data for which user?</source>
- <translation type="unfinished"/>
+ <translation>إرسال حفظ البيانات لأي مستخدم؟</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="226"/>
<source>Select a user:</source>
- <translation>اختر مستخدم:</translation>
+ <translation>:اختر مستخدم</translation>
</message>
</context>
<context>
@@ -7059,17 +7156,17 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="202"/>
<source>runnable</source>
- <translation type="unfinished"/>
+ <translation>قابل للتشغيل</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="204"/>
<source>paused</source>
- <translation type="unfinished"/>
+ <translation>متوقف مؤقتا</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="210"/>
<source>sleeping</source>
- <translation type="unfinished"/>
+ <translation>نائم</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="213"/>
@@ -7109,7 +7206,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="236"/>
<source>terminated</source>
- <translation type="unfinished"/>
+ <translation>تم إنهاؤه</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="239"/>
@@ -7119,7 +7216,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="244"/>
<source> PC = 0x%1 LR = 0x%2</source>
- <translation type="unfinished"/>
+ <translation> PC = 0x%1 LR = 0x%2</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="294"/>
diff --git a/dist/languages/ca.ts b/dist/languages/ca.ts
index 0ececae42..65b8ca894 100644
--- a/dist/languages/ca.ts
+++ b/dist/languages/ca.ts
@@ -365,13 +365,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -882,49 +882,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Activa els serveis d&apos;informes detallats**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Això es restablirà automàticament quan es tanqui yuzu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation type="unfinished"/>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation type="unfinished"/>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1343,7 +1323,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Seqüència de tecles en conflicte</translation>
</message>
@@ -1364,27 +1344,37 @@ This would ban both their forum username and their IP address.</source>
<translation>Invàlid</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Restaurar el valor predeterminat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Esborrar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Seqüència de botons en conflicte</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>La seqüència de botons per defecte ja està assignada a: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>La seqüència de tecles predeterminada ja ha estat assignada a: %1</translation>
</message>
@@ -3360,67 +3350,72 @@ Arrossegui els punts per a canviar la posició, o faci doble clic a les cel·les
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Tamany de les icones dels jocs</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Tamany de les icones de les carpetes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Text de la fila 1:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Text de la fila 2:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Captures de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Preguntar on guardar les captures de pantalla (només Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Ruta de les captures de pantalla:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Resolució:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Seleccioni el directori de les Captures de Pantalla...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3738,612 +3733,616 @@ Arrossegui els punts per a canviar la posició, o faci doble clic a les cel·les
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Es recullen dades anònimes&lt;/a&gt; per ajudar a millorar yuzu. &lt;br/&gt;&lt;br/&gt;Desitja compartir les seves dades d&apos;ús amb nosaltres?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Carregant Web applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Desactivar el Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Desactivar l&apos;Applet Web pot provocar comportaments indefinits i només hauria d&apos;utilitzar-se amb Super Mario 3D All-Stars. Estàs segur de que vols desactivar l&apos;Applet Web?
(Això pot ser reactivat als paràmetres Debug.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>La quantitat de shaders que s&apos;estan compilant actualment</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>El multiplicador d&apos;escala de resolució seleccionat actualment.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocitat d&apos;emulació actual. Valors superiors o inferiors a 100% indiquen que l&apos;emulació s&apos;està executant més ràpidament o més lentament que a la Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Quants fotogrames per segon està mostrant el joc actualment. Això variarà d&apos;un joc a un altre i d&apos;una escena a una altra.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Temps que costa emular un fotograma de la Switch, sense tenir en compte la limitació de fotogrames o la sincronització vertical. Per a una emulació òptima, aquest valor hauria de ser com a màxim de 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Esborrar arxius recents</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Advertència format del joc desfasat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Està utilitzant el format de directori de ROM deconstruït per a aquest joc, que és un format desactualitzat que ha sigut reemplaçat per altres, com NCA, NAX, XCI o NSP. Els directoris de ROM deconstruïts careixen d&apos;icones, metadades i suport d&apos;actualitzacions.&lt;br&gt;&lt;br&gt;Per a obtenir una explicació dels diversos formats de Switch que suporta yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;faci una ullada a la nostra wiki&lt;/a&gt;. Aquest missatge no es tornarà a mostrar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Error carregant la ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>El format de la ROM no està suportat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>S&apos;ha produït un error inicialitzant el nucli de vídeo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu ha trobat un error mentre executava el nucli de vídeo. Això sol ser causat per controladors de la GPU obsolets, inclosos els integrats. Si us plau, consulti el registre per a més detalls. Per obtenir més informació sobre com accedir al registre, consulti la següent pàgina: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Com carregar el fitxer de registre&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Error al carregar la ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Si us plau, segueixi &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guia d&apos;inici de yuzu&lt;/a&gt; per a bolcar de nou els seus fitxers.&lt;br&gt;Pot consultar la wiki de yuzu wiki&lt;/a&gt; o el Discord de yuzu&lt;/a&gt; per obtenir ajuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>S&apos;ha produït un error desconegut. Si us plau, consulti el registre per a més detalls.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>S&apos;està tancant el programari</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Dades de partides guardades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Dades de mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Error obrint la carpeta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>La carpeta no existeix!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Error obrint la cache transferible de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>No s&apos;ha pogut crear el directori de la cache dels shaders per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Eliminar entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>S&apos;ha eliminat correctament</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>S&apos;ha eliminat correctament el joc base instal·lat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>El joc base no està instal·lat a la NAND i no pot ser eliminat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>S&apos;ha eliminat correctament l&apos;actualització instal·lada.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>No hi ha cap actualització instal·lada per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>No hi ha cap DLC instal·lat per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>S&apos;ha eliminat correctament %1 DLC instal·lat/s.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Desitja eliminar la cache transferible de shaders d&apos;OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Desitja eliminar la cache transferible de shaders de Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Desitja eliminar totes les caches transferibles de shaders?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Desitja eliminar la configuració personalitzada del joc?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Eliminar arxiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Error eliminant la cache transferible de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>No existeix una cache de shaders per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>S&apos;ha eliminat correctament la cache transferible de shaders.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>No s&apos;ha pogut eliminar la cache transferible de shaders.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Error al eliminar les caches de shaders transferibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Caches de shaders transferibles eliminades correctament.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>No s&apos;ha pogut eliminar el directori de caches de shaders transferibles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Error eliminant la configuració personalitzada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>No existeix una configuració personalitzada per aquest joc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>S&apos;ha eliminat correctament la configuració personalitzada del joc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>No s&apos;ha pogut eliminar la configuració personalitzada del joc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>La extracció de RomFS ha fallat!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>S&apos;ha produït un error copiant els arxius RomFS o l&apos;usuari ha cancel·lat la operació.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Esquelet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Seleccioni el mode de bolcat de RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Si us plau, seleccioni la forma en que desitja bolcar la RomFS.&lt;br&gt;Completa copiarà tots els arxius al nou directori mentre que&lt;br&gt;esquelet només crearà l&apos;estructura de directoris.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>No hi ha suficient espai lliure a %1 per extreure el RomFS. Si us plau, alliberi espai o esculli un altre directori de bolcat a Emulació &gt; Configuració &gt; Sistema &gt; Sistema d&apos;arxius &gt; Carpeta arrel de bolcat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Extraient RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Cancel·la</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extracció de RomFS completada correctament!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>L&apos;operació s&apos;ha completat correctament.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Error obrint %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Seleccionar directori</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Propietats</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Les propietats del joc no s&apos;han pogut carregar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Executable de Switch (%1);;Tots els Arxius (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Carregar arxiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Obrir el directori de la ROM extreta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Directori seleccionat invàlid</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>El directori que ha seleccionat no conté un arxiu &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Arxiu de Switch Instal·lable (*.nca *.nsp *.xci);;Arxiu de Continguts Nintendo (*.nca);;Paquet d&apos;enviament Nintendo (*.nsp);;Imatge de Cartutx NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Instal·lar arxius</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n arxiu(s) restants</numerusform><numerusform>%n arxiu(s) restants</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instal·lant arxiu &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Resultats instal·lació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Per evitar possibles conflictes, no recomanem als usuaris que instal·lin jocs base a la NAND.
Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i DLCs.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n nou(s) arxiu(s) s&apos;ha(n) instal·lat
@@ -4351,7 +4350,7 @@ Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n arxiu(s) s&apos;han sobreescrit
@@ -4359,7 +4358,7 @@ Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n arxiu(s) no s&apos;han instal·lat
@@ -4367,339 +4366,371 @@ Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Aplicació del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Arxiu del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Actualització de l&apos;aplicació del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Paquet de firmware (Tipus A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Paquet de firmware (Tipus B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Actualització de joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC del joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Títol delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Seleccioni el tipus d&apos;instal·lació NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Seleccioni el tipus de títol que desitja instal·lar aquest NCA com a:
(En la majoria dels casos, el valor predeterminat &apos;Joc&apos; està bé.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Ha fallat la instal·lació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>El tipus de títol seleccionat per el NCA és invàlid.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Arxiu no trobat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Arxiu &quot;%1&quot; no trobat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>D&apos;acord</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Falta el compte de yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Per tal d&apos;enviar un cas de prova de compatibilitat de joc, ha de vincular el seu compte de yuzu.&lt;br&gt;&lt;br/&gt;Per a vincular el seu compte de yuzu, vagi a Emulació &amp; gt; Configuració &amp; gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Error obrint URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>No es pot obrir la URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Gravació TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Sobreescriure l&apos;arxiu del jugador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Configuració invàlida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>El controlador del mode portàtil no es pot fer servir en el mode acoblat. Es seleccionarà el controlador Pro en el seu lloc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>L&apos;amiibo actual ha sigut eliminat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>El joc actual no està buscant amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Arxiu Amiibo (%1);; Tots els Arxius (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Carregar Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Error al carregar les dades d&apos;Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Imatge PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Estat TAS: executant %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Estat TAS: gravant %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Estat TAS: inactiu %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Estat TAS: invàlid</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar l&apos;execució</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Parar g&amp;ravació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravar</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Construint: %n shader(s)</numerusform><numerusform>Construint: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Velocitat: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Velocitat: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Joc: %1 FPS (desbloquejat)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Joc: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Fotograma: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>SENSE AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmi la clau de rederivació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4716,37 +4747,37 @@ i opcionalment faci còpies de seguretat.
Això eliminarà els arxius de les claus generats automàticament i tornarà a executar el mòdul de derivació de claus.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Falten fusibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - Falta BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Falta BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Falta PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Falten components de derivació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Falten les claus d&apos;encriptació. &lt;br&gt;Si us plau, segueixi &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guia ràpida de yuzu&lt;/a&gt; per a obtenir totes les seves claus, firmware i jocs.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4755,49 +4786,49 @@ Això pot prendre fins a un minut depenent
del rendiment del seu sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Derivant claus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Seleccioni el destinatari per a bolcar el RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Si us plau, seleccioni quin RomFS desitja bolcar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Està segur de que vol tancar yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Està segur de que vol aturar l&apos;emulació? Qualsevol progrés no guardat es perdrà.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4949,241 +4980,251 @@ Desitja tancar-lo de totes maneres?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Preferit</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Iniciar el joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Iniciar el joc sense la configuració personalitzada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Obrir la ubicació dels arxius de partides guardades</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Obrir la ubicació dels mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Obrir cache transferible de shaders de canonada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Eliminar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Eliminar actualització instal·lada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Eliminar tots els DLC instal·lats</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Eliminar configuració personalitzada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Eliminar cache de canonada d&apos;OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Eliminar cache de canonada de Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Eliminar totes les caches de canonada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Eliminar tots els continguts instal·lats</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Bolcar RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Bolcar RomFS a SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Copiar la ID del títol al porta-retalls</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Navegar a l&apos;entrada de GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Propietats</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Escanejar subdirectoris</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Eliminar directori de jocs</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Moure amunt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Move avall</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Obre ubicació del directori</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Esborrar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nom</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Compatibilitat</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Complements</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Tipus d&apos;arxiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Mida</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfecte</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro / Menú</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>No engega</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>El joc es bloqueja al intentar iniciar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>No provat</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Aquest joc encara no ha estat provat.</translation>
</message>
@@ -5191,7 +5232,7 @@ Desitja tancar-lo de totes maneres?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Faci doble clic per afegir un nou directori a la llista de jocs</translation>
</message>
@@ -5204,12 +5245,12 @@ Desitja tancar-lo de totes maneres?</translation>
<translation><numerusform>%1 de %n resultat(s)</numerusform><numerusform>%1 de %n resultat(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filtre:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Introdueixi patró per a filtrar</translation>
</message>
@@ -5326,6 +5367,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
@@ -5431,6 +5473,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5669,186 +5716,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Ajuda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;instal·lar arxius a la NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>C&amp;arregar arxiu...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Carregar &amp;carpeta...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>S&amp;ortir</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Aturar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Reinicialitzar claus...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Sobre yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Mode una sola &amp;finestra</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Con&amp;figurar...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Mostrar complements de capçalera del D&amp;ock</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Mostrar la barra de &amp;filtre</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Mostrar la barra d&apos;&amp;estat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Mostrar barra d&apos;estat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>P&amp;antalla completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Reiniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Carregar/Eliminar &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Informar de compatibilitat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Obrir la pàgina de &amp;mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Obre la guia d&apos;&amp;inici ràpid</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;Preguntes freqüents</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Obrir la carpeta de &amp;yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Configurar TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Configurar joc a&amp;ctual...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Reiniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>E&amp;nregistrar</translation>
</message>
@@ -6152,27 +6229,27 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Títols instal·lats a la SD</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Títols instal·lats a la NAND</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Títols del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Afegir un nou directori de jocs</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Preferits</translation>
</message>
@@ -6698,7 +6775,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Controlador Pro</translation>
</message>
@@ -6711,7 +6788,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Joycons duals</translation>
</message>
@@ -6724,7 +6801,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon esquerra</translation>
</message>
@@ -6737,7 +6814,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon dret</translation>
</message>
@@ -6766,7 +6843,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Portàtil</translation>
</message>
@@ -6882,32 +6959,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Controlador de GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Controlador NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Controlador SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Controlador N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/cs.ts b/dist/languages/cs.ts
index 899725ed4..efe3559b6 100644
--- a/dist/languages/cs.ts
+++ b/dist/languages/cs.ts
@@ -365,13 +365,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -876,49 +876,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation type="unfinished"/>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation type="unfinished"/>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1337,7 +1317,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Protichůdné klávesové sekvence</translation>
</message>
@@ -1358,27 +1338,37 @@ This would ban both their forum username and their IP address.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Vrátit výchozí nastavení</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Vyčistit</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Výchozí klávesová sekvence je již přiřazena k: %1</translation>
</message>
@@ -3354,67 +3344,72 @@ Táhněte body pro změnu pozice nebo dvojitě klikněte na buňky tabulky pro z
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Text řádku 1:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Text řádku 2:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Snímek obrazovky</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Zeptat se, kam uložit snímek obrazovky (pouze Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Cesta snímků obrazovky:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Vyberte cestu ke snímkům obrazovky...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3732,961 +3727,997 @@ Táhněte body pro změnu pozice nebo dvojitě klikněte na buňky tabulky pro z
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymní data jsou sbírána&lt;/a&gt; pro vylepšení yuzu. &lt;br/&gt;&lt;br/&gt;Chcete s námi sdílet anonymní data?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Načítání Web Appletu...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Zakázat Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Počet aktuálně sestavovaných shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Aktuální emulační rychlost. Hodnoty vyšší než 100% indikují, že emulace běží rychleji nebo pomaleji než na Switchi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Kolik snímků za sekundu aktuálně hra zobrazuje. Tohle závisí na hře od hry a scény od scény.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Čas potřebný na emulaci framu scény, nepočítá se limit nebo v-sync. Pro plnou rychlost by se tohle mělo pohybovat okolo 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Vymazat poslední soubory</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Pokračovat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pauza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Varování Zastaralý Formát Hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Používáte rozbalený formát hry, který je zastaralý a byl nahrazen jinými jako NCA, NAX, XCI, nebo NSP. Rozbalená ROM nemá ikony, metadata, a podporu updatů.&lt;br&gt;&lt;br&gt;Pro vysvětlení všech možných podporovaných typů, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;zkoukni naší wiki&lt;/a&gt;. Tato zpráva se nebude znova zobrazovat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Chyba při načítání ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Tento formát ROM není podporován.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Nastala chyba při inicializaci jádra videa.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Chyba při načítání ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Pro extrakci souborů postupujte podle &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;rychlého průvodce yuzu&lt;/a&gt;. Nápovědu naleznete na &lt;br&gt;wiki&lt;/a&gt; nebo na Discordu&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Nastala chyba. Koukni do logu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Uložit data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Módovat Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Chyba otevírání složky %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Složka neexistuje!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Chyba při otevírání přenositelné mezipaměti shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Odebrat položku</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Úspěšně odebráno</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Úspěšně odebrán nainstalovaný základ hry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Základ hry není nainstalovaný na NAND a nemůže být odstraněn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Úspěšně odebrána nainstalovaná aktualizace.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Není nainstalovaná žádná aktualizace pro tento titul.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Není nainstalované žádné DLC pro tento titul.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Úspěšně odstraněno %1 nainstalovaných DLC.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Odstranit vlastní konfiguraci hry?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Odstranit soubor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Chyba při odstraňování přenositelné mezipaměti shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Mezipaměť shaderů pro tento titul neexistuje.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Přenositelná mezipaměť shaderů úspěšně odstraněna</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Nepodařilo se odstranit přenositelnou mezipaměť shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Chyba při odstraňování vlastní konfigurace hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Vlastní konfigurace hry pro tento titul neexistuje.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Úspěšně odstraněna vlastní konfigurace hry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Nepodařilo se odstranit vlastní konfiguraci hry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Extrakce RomFS se nepovedla!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Nastala chyba při kopírování RomFS souborů, nebo uživatel operaci zrušil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Plný</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Kostra</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Vyber RomFS Dump Mode</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Vyber jak by si chtěl RomFS vypsat.&lt;br&gt;Plné zkopíruje úplně všechno, ale&lt;br&gt;kostra zkopíruje jen strukturu složky.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Extrahuji RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Zrušit</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extrakce RomFS se povedla!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Operace byla dokončena úspěšně.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Chyba při otevírání %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Vybraná Složka</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Vlastnosti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Herní vlastnosti nemohly být načteny.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Executable (%1);;Všechny soubory (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Načíst soubor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Otevřít složku s extrahovanou ROM</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Vybraná složka je neplatná</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Složka kterou jste vybrali neobsahuje soubor &quot;main&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Instalovatelný soubor pro Switch (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Instalovat Soubory</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalování souboru &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Výsledek instalace</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Abychom předešli možným konfliktům, nedoporučujeme uživatelům instalovat základní hry na paměť NAND.
Tuto funkci prosím používejte pouze k instalaci aktualizací a DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Systémová Aplikace</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Systémový archív</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Systémový Update Aplikace</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Firmware-ový baliček (Typu A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Firmware-ový baliček (Typu B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Hra</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Update Hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Herní DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta Title</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Vyberte typ instalace NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vyberte typ title-u, který chcete nainstalovat tenhle NCA jako:
(Většinou základní &quot;game&quot; stačí.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Chyba v instalaci</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Tento typ pro tento NCA není platný.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Soubor nenalezen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Soubor &quot;%1&quot; nenalezen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Chybí účet yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Pro přidání recenze kompatibility je třeba mít účet yuzu&lt;br&gt;&lt;br/&gt;Pro nalinkování yuzu účtu jdi do Emulace &amp;gt; Konfigurace &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Chyba při otevírání URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Nelze otevřít URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Zjištěno neplatné nastavení</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Ruční ovladač nelze používat v dokovacím režimu. Bude vybrán ovladač Pro Controller.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Soubor Amiibo (%1);; Všechny Soubory (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Načíst Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Chyba načítání Amiiba</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Pořídit Snímek Obrazovky</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG Image (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Rychlost: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Rychlost: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Hra: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Potvďte Rederivaci Klíčů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4703,37 +4734,37 @@ a udělejte si zálohu.
Toto vymaže věechny vaše automaticky generované klíče a znova spustí modul derivace klíčů.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Chybí Fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Chybí BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Chybí BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Chybí PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Chybé odvozené komponenty</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4742,49 +4773,49 @@ Tohle může zabrat až minutu
podle výkonu systému.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Derivuji Klíče</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Vyberte Cíl vypsaní RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vyberte, kterou RomFS chcete vypsat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Jste si jist, že chcete zavřít yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Jste si jist, že chcete ukončit emulaci? Jakýkolic neuložený postup bude ztracen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4936,241 +4967,251 @@ Opravdu si přejete ukončit tuto aplikaci?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Oblíbené</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Spustit hru</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Spustit hru bez vlastní konfigurace</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Otevřít Lokaci Savů</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Otevřít Lokaci Modifikací</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Odstranit</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Odstranit nainstalovanou aktualizaci</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Odstranit všechny nainstalované DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Odstranit vlastní konfiguraci hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Odstranit všechen nainstalovaný obsah</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Vypsat RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Zkopírovat ID Titulu do schránky</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Navigovat do GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Vlastnosti</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Prohledat podsložky</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Odstranit složku se hrou</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Posunout nahoru</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Posunout dolů</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Otevřít umístění složky</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Vymazat</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Název</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatibilita</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Modifkace</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Typ-Souboru</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Velikost</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfektní</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Nebootuje</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Hra crashuje při startu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Netestováno</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Hra ještě nebyla testována</translation>
</message>
@@ -5178,7 +5219,7 @@ Opravdu si přejete ukončit tuto aplikaci?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Dvojitým kliknutím přidáte novou složku do seznamu her</translation>
</message>
@@ -5191,12 +5232,12 @@ Opravdu si přejete ukončit tuto aplikaci?</translation>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filtr:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Zadejte filtr</translation>
</message>
@@ -5313,6 +5354,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
@@ -5418,6 +5460,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5655,186 +5702,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Pomoc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Instalovat soubory na NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>Načís&amp;t soubor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Načíst sl&amp;ožku...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>E&amp;xit</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pauza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Stop</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Znovu inicializovat klíče...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>O &amp;aplikaci yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>&amp;Režim jednoho okna</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>&amp;Nastavení</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Zobrazit záhlaví widgetů d&amp;oku</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Zobrazit &amp;filtrovací panel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Zobrazit &amp;stavový řádek</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Zobrazit Staus Bar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>&amp;Celá obrazovka</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Restartovat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Nahlásit kompatibilitu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Otevřít stránku s &amp;modifikacemi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Otevřít &amp;rychlého průvodce</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>Často &amp;kladené otázky</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Otevřít složku s &amp;yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>Za&amp;chytit snímek obrazovky</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Nastavení současné hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
@@ -6138,27 +6215,27 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Nainstalované SD tituly</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Nainstalované NAND tituly</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Systémové tituly</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Přidat novou složku s hrami</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Oblíbené</translation>
</message>
@@ -6684,7 +6761,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6697,7 +6774,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Oba Joycony</translation>
</message>
@@ -6710,7 +6787,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Levý Joycon</translation>
</message>
@@ -6723,7 +6800,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Pravý Joycon</translation>
</message>
@@ -6752,7 +6829,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
@@ -6868,32 +6945,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Ovladač GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/da.ts b/dist/languages/da.ts
index 96fa73cc0..da4816f5b 100644
--- a/dist/languages/da.ts
+++ b/dist/languages/da.ts
@@ -373,13 +373,13 @@ Dette vil bandlyse både vedkommendes forum-brugernavn og IP-adresse.</translati
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -890,49 +890,29 @@ Dette vil bandlyse både vedkommendes forum-brugernavn og IP-adresse.</translati
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Opret Minidump Efter Nedbrud</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Aktivér dette, for at udgyde den senest genererede lyd-kommandoliste til konsollen. Påvirker kun spil, som gør brug af lyd-renderingen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Dump Lydkommandoer Til Konsol**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Aktivér Vitterlig Rapporteringstjeneste</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Dette vil automatisk blive nulstillet, når yuzu lukkes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Genstart Kræves</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>Yuzu kræver en genstart, for at anvende denne indstilling.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Net-applet ikke kompileret</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>MiniDump oprettelse ikke kompileret</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1351,7 +1331,7 @@ Dette vil bandlyse både vedkommendes forum-brugernavn og IP-adresse.</translati
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Modstridende Tastesekvens</translation>
</message>
@@ -1372,27 +1352,37 @@ Dette vil bandlyse både vedkommendes forum-brugernavn og IP-adresse.</translati
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Gendan Standard</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Ryd</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Standard-tastesekvensen er allerede tilegnet: %1</translation>
</message>
@@ -3368,67 +3358,72 @@ Træk punkter, for at skifte position, eller dobbeltklik i tabelceller, for at r
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Spil-Ikonstørrelse:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Mappe-Ikonstørrelse:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Række 1-Tekst:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Række 2-Tekst:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Skærmbilleder</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Spørg Hvor Skærmbilleder Skal Gemmes (Kun Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Skærmbilledsti:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Opløsning:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Vælg Skærmbilledsti...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3746,959 +3741,995 @@ Træk punkter, for at skifte position, eller dobbeltklik i tabelceller, for at r
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonym data indsamles&lt;/a&gt;, for at hjælp med, at forbedre yuzu. &lt;br/&gt;&lt;br/&gt;Kunne du tænke dig, at dele dine brugsdata med os?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Indlæser Net-Applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Deaktivér Net-Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Aktuel emuleringshastighed. Værdier højere eller lavere end 100% indikerer, at emulering kører hurtigere eller langsommere end en Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Advarsel, Forældet Spilformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Fejl under indlæsning af ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>ROM-formatet understøttes ikke.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Der skete en fejl under initialisering af video-kerne.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Fejl ved Åbning af %1 Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Mappe eksisterer ikke!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS-Udpakning Mislykkedes!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Der skete en fejl ved kopiering af RomFS-filerne, eller brugeren afbrød opgaven.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Fuld</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Skelet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Vælg RomFS-Nedfældelsestilstand</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Udpakker RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Afbryd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS-Udpakning Lykkedes!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Fuldførelse af opgaven lykkedes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Fejl ved Åbning af %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Vælg Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Egenskaber</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Spil-egenskaberne kunne ikke indlæses.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch-Eksekverbar (%1);;Alle filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Indlæs Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Åbn Udpakket ROM-Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Ugyldig Mappe Valgt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installér fil &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Systemapplikation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Systemarkiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Systemapplikationsopdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Firmwarepakke (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Firmwarepakke (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Spil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Spilopdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Spiludvidelse</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta-Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Vælg NCA-Installationstype...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Installation mislykkedes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Fil ikke fundet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Fil &quot;%1&quot; ikke fundet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Manglende yuzu-Konto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo-Fil (%1);; Alle Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Indlæs Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Fejl ved indlæsning af Amiibo-data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Optag Skærmbillede</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG-Billede (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Hastighed: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Hastighed: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Spil: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Billede: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4709,86 +4740,86 @@ This will delete your autogenerated key files and re-run the key derivation modu
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Er du sikker på, at du vil lukke yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Er du sikker på, at du vil stoppe emulereingen? Enhver ulagret data, vil gå tabt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4938,241 +4969,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Åbn Gemt Data-Placering</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Åbn Mod-Data-Placering</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Fjern</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Kopiér Titel-ID til Udklipsholder</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Egenskaber</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Ryd</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Navn</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatibilitet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Tilføjelser</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Filtype</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Størrelse</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Starter Ikke Op</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Ikke Afprøvet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Spillet er endnu ikke blevet afprøvet.</translation>
</message>
@@ -5180,7 +5221,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation type="unfinished"/>
</message>
@@ -5193,12 +5234,12 @@ Would you like to bypass this and exit anyway?</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filter:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation type="unfinished"/>
</message>
@@ -5315,6 +5356,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
@@ -5420,6 +5462,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5657,186 +5704,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Hjælp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Vis Statuslinje</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
@@ -6136,27 +6213,27 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Installerede SD-Titler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Installerede NAND-Titler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Systemtitler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Tilføj Ny Spilmappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation type="unfinished"/>
</message>
@@ -6682,7 +6759,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro-Styringsenhed</translation>
</message>
@@ -6695,7 +6772,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Dobbelt-Joycon</translation>
</message>
@@ -6708,7 +6785,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Venstre Joycon</translation>
</message>
@@ -6721,7 +6798,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Højre Joycon</translation>
</message>
@@ -6750,7 +6827,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Håndholdt</translation>
</message>
@@ -6866,32 +6943,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube-Styringsenhed</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/de.ts b/dist/languages/de.ts
index 263c11158..e11d96da6 100644
--- a/dist/languages/de.ts
+++ b/dist/languages/de.ts
@@ -372,16 +372,16 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
- <translation type="unfinished"/>
+ <translation>Automatisch (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
- <translation type="unfinished"/>
+ <translation>Standard (%1)</translation>
</message>
</context>
<context>
@@ -756,7 +756,7 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="269"/>
<source>Disable Loop safety checks</source>
- <translation type="unfinished"/>
+ <translation>Loop-safety-checks deaktivieren</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="279"/>
@@ -831,7 +831,7 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="377"/>
<source>Enable Renderdoc Hotkey</source>
- <translation type="unfinished"/>
+ <translation>Renderdoc-Hotkey aktivieren</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="387"/>
@@ -890,49 +890,29 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Minidump nach Absturz erstellen</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Aktivieren Sie diese Option, um den zuletzt generierten Audio-Log auf der Konsole auszugeben. Betrifft nur Spiele, die den Audio-Renderer verwenden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation> Audio-Befehle auf die Konsole als Dump abspeichern**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation> Ausführliche Berichtsdienste aktivieren**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Dies wird automatisch beim Schließen von yuzu zurückgesetzt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Neustart erforderlich</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu muss neugestartet werden, damit diese Einstellungen übernommen werden können. </translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Web-Applet nicht kompiliert</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>MiniDump-Erstellung nicht kompiliert</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1351,7 +1331,7 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Tastensequenz bereits belegt</translation>
</message>
@@ -1372,27 +1352,37 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
<translation>Ungültig</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>Ungültige Hotkey-Einstellungen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Standardwerte wiederherstellen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Löschen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Widersprüchliche Tastenfolge</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Die Standard Tastenfolge ist bereits belegt von: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Die Standard-Sequenz ist bereits vergeben an: %1</translation>
</message>
@@ -1678,7 +1668,7 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2595"/>
<source>Debug Controller</source>
- <translation>Debug Controller</translation>
+ <translation>Debug-Controller</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2602"/>
@@ -2068,7 +2058,7 @@ Dies würde deren Forum Benutzernamen und deren IP-Adresse sperren.</translation
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3085"/>
<source>Mouse panning</source>
- <translation type="unfinished"/>
+ <translation>Maus-Panning</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3109"/>
@@ -2366,7 +2356,7 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="57"/>
<source>Touch from button profile:</source>
- <translation type="unfinished"/>
+ <translation>Berührung des Button-Profils:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="85"/>
@@ -2505,7 +2495,7 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="15"/>
<source>Can be toggled via a hotkey. Default hotkey is Ctrl + F9</source>
- <translation type="unfinished"/>
+ <translation>Kann mit einem Hotkey umgeschaltet werden. Standard-Hotkey ist STRG + F9</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="24"/>
@@ -2539,17 +2529,17 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="88"/>
<source>Counteracts a game&apos;s built-in deadzone</source>
- <translation type="unfinished"/>
+ <translation>Überschreibt spieleigene Deadzone</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="94"/>
<source>Deadzone</source>
- <translation type="unfinished"/>
+ <translation>Deadzone</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="123"/>
<source>Stick decay</source>
- <translation type="unfinished"/>
+ <translation>Stick Abklingzeit</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="129"/>
@@ -2570,7 +2560,8 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<location filename="../../src/yuzu/configuration/configure_mouse_panning.cpp" line="43"/>
<source>Mouse panning works better with a deadzone of 0% and a range of 100%.
Current values are %1% and %2% respectively.</source>
- <translation type="unfinished"/>
+ <translation>Das Bewegen der Maus funktioniert mit einer Deadzone zwischen 0% und 100% besser.
+Aktuell liegen die Werte bei %1% bzw. %2%.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.cpp" line="50"/>
@@ -2889,7 +2880,8 @@ Current values are %1% and %2% respectively.</source>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="360"/>
<source>Name: %1
UUID: %2</source>
- <translation type="unfinished"/>
+ <translation>Name: %1
+UUID: %2</translation>
</message>
</context>
<context>
@@ -2902,7 +2894,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="26"/>
<source>To use Ring-Con, configure player 1 as right Joy-Con (both physical and emulated), and player 2 as left Joy-Con (left physical and dual emulated) before starting the game.</source>
- <translation type="unfinished"/>
+ <translation>Um einen Ring-Con zu nutzen, konfiguriere Spieler 1 als rechten Joy-Con (als Eingabegerät und emulierter Controller), und Spieler 2 als linken Joy-Con (linker Joy-Con als Eingabegerät und als zwei Joy-Cons emuliert) vor dem Starten des Spieles.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="52"/>
@@ -3002,7 +2994,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="306"/>
<source>The current mapped device doesn&apos;t have a ring attached</source>
- <translation type="unfinished"/>
+ <translation>Das aktuell genutzte Gerät ist nicht mit dem Ring-Con verbunden</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="309"/>
@@ -3036,7 +3028,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_system.ui" line="62"/>
<source>Core</source>
- <translation type="unfinished"/>
+ <translation>Kern</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_system.cpp" line="62"/>
@@ -3084,7 +3076,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
- <translation type="unfinished"/>
+ <translation>Pausiere Ausführung während des Ladens</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
@@ -3360,78 +3352,83 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="96"/>
<source>Show Size Column</source>
- <translation type="unfinished"/>
+ <translation>&quot;Größe&quot;-Spalte anzeigen</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="103"/>
<source>Show File Types Column</source>
- <translation type="unfinished"/>
+ <translation>&quot;Dateityp&quot;-Spalte anzeigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>&quot;Spielzeit&quot;-Spalte anzeigen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Spiel-Icon Größe:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Ordner-Icon Größe:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Zeile 1 Text:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Zeile 2 Text:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Screenshots</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Frage nach, wo Screenshots gespeichert werden sollen (Nur Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Screenshotpfad</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
- <translation type="unfinished"/>
+ <translation>TextLabel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Auflösung:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Screenshotpfad auswählen...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
- <translation type="unfinished"/>
+ <translation>Auto (%1 x %2, %3 x %4)</translation>
</message>
</context>
<context>
@@ -3565,7 +3562,7 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
- <translation type="unfinished"/>
+ <translation>Die Konfiguration des Webservice kann nur geändert werden, wenn kein öffentlicher Raum gehostet wird.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="128"/>
@@ -3643,7 +3640,7 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
<source>Unverified, please click Verify before saving configuration</source>
<comment>Tooltip</comment>
- <translation type="unfinished"/>
+ <translation>Nicht verifiziert, vor dem Speichern Verifizieren wählen</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
@@ -3712,7 +3709,7 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="71"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Port number the host is listening on&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Port, welcher vom Host zum Empfangen verwendet wird&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="97"/>
@@ -3746,613 +3743,618 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonyme Daten werden gesammelt,&lt;/a&gt; um yuzu zu verbessern.&lt;br/&gt;&lt;br/&gt;Möchstest du deine Nutzungsdaten mit uns teilen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetrie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Defekte Vulkan-Installation erkannt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Vulkan Initialisierung fehlgeschlagen.&lt;br&gt;&lt;br&gt;Klicken Sie auf &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;für Instruktionen zur Problembehebung.&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
- <translation type="unfinished"/>
+ <translation>Spiel wird ausgeführt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Lade Web-Applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Deaktiviere die Web Applikation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
- <translation type="unfinished"/>
+ <translation>Deaktivieren des Web-Applets kann zu undefiniertem Verhalten führen, und sollte nur mit Super Mario 3D All-Stars benutzt werden. Bist du sicher, dass du das Web-Applet deaktivieren möchtest?
+(Dies kann in den Debug-Einstellungen wieder aktiviert werden.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Wie viele Shader im Moment kompiliert werden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Der momentan ausgewählte Auflösungsskalierung Multiplikator.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Derzeitige Emulations-Geschwindigkeit. Werte höher oder niedriger als 100% zeigen, dass die Emulation scheller oder langsamer läuft als auf einer Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Wie viele Bilder pro Sekunde angezeigt werden variiert von Spiel zu Spiel und von Szene zu Szene. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Zeit, die gebraucht wurde, um einen Switch-Frame zu emulieren, ohne Framelimit oder V-Sync. Für eine Emulation bei voller Geschwindigkeit sollte dieser Wert bei höchstens 16.67ms liegen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Ton aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Stummschalten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Ton zurücksetzen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Zuletzt geladene Dateien leeren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Emulierte Maus ist aktiviert</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Echte Mauseingabe und Mausschwenken sind nicht kompatibel. Bitte deaktivieren Sie die emulierte Maus in den erweiterten Eingabeeinstellungen, um das Schwenken der Maus zu ermöglichen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Fortsetzen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Warnung veraltetes Spielformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Du nutzt eine entpackte ROM-Ordnerstruktur für dieses Spiel, welches ein veraltetes Format ist und von anderen Formaten wie NCA, NAX, XCI oder NSP überholt wurde. Entpackte ROM-Ordner unterstützen keine Icons, Metadaten oder Updates.&lt;br&gt;&lt;br&gt;&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Unser Wiki&lt;/a&gt; enthält eine Erklärung der verschiedenen Formate, die yuzu unterstützt. Diese Nachricht wird nicht noch einmal angezeigt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>ROM konnte nicht geladen werden!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>ROM-Format wird nicht unterstützt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Beim Initialisieren des Video-Kerns ist ein Fehler aufgetreten.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>Yuzu ist auf einen Fehler gestoßen beim Ausführen des Videokerns.
Dies ist in der Regel auf veraltete GPU Treiber zurückzuführen, integrierte GPUs eingeschlossen.
Bitte öffnen Sie die Log Datei für weitere Informationen. Für weitere Informationen wie Sie auf die Log Datei zugreifen, öffnen Sie bitte die folgende Seite: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Wie wird eine Log Datei hochgeladen?&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROM konnte nicht geladen werden! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Bitte folge der &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu-Schnellstart-Anleitung&lt;/a&gt; um deine Dateien zu extrahieren.&lt;br&gt;Hilfe findest du im yuzu-Wiki&lt;/a&gt; oder dem yuzu-Discord&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ein unbekannter Fehler ist aufgetreten. Bitte prüfe die Log-Dateien auf mögliche Fehlermeldungen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-Bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-Bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Schließe Software...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Speicherdaten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod-Daten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Konnte Verzeichnis %1 nicht öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Verzeichnis existiert nicht!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Fehler beim Öffnen des transferierbaren Shader-Caches</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Fehler beim erstellen des Shader-Cache-Ordner für den ausgewählten Titel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Fehler beim Entfernen des Inhalts</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Fehler beim Entfernen des Updates</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Fehler beim Entfernen des DLCs</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Installierten Spiele-Content entfernen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Installierte Spiele-Updates entfernen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Installierte Spiele-DLCs entfernen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Eintrag entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Erfolgreich entfernt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Das Spiel wurde entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Das Spiel ist nicht im NAND installiert und kann somit nicht entfernt werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Das Update wurde entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Es ist kein Update für diesen Titel installiert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Es sind keine DLC für diesen Titel installiert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 DLC entfernt. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Transferierbaren OpenGL Shader Cache löschen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Transferierbaren Vulkan Shader Cache löschen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Alle transferierbaren Shader Caches löschen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Spiel-Einstellungen entfernen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Cache-Speicher entfernen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Datei entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>Spielzeit-Daten enfernen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>Spielzeit zurücksetzen?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Fehler beim Entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Es existiert kein Shader-Cache für diesen Titel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Der transferierbare Shader-Cache wurde entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Konnte den transferierbaren Shader-Cache nicht entfernen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Fehler beim Entfernen des Vulkan-Pipeline-Cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Fehler beim Entfernen des Driver-Pipeline-Cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Fehler beim Entfernen der transferierbaren Shader Caches</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Die übertragbaren Shader-Caches wurden erfolgreich entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
- <translation type="unfinished"/>
+ <translation>Entfernen des transferierbaren Shader-Cache-Verzeichnisses fehlgeschlagen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Fehler beim Entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Es existieren keine Spiel-Einstellungen für dieses Spiel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Die Spiel-Einstellungen wurden entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Die Spiel-Einstellungen konnten nicht entfernt werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS-Extraktion fehlgeschlagen!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Das RomFS konnte wegen eines Fehlers oder Abbruchs nicht kopiert werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Komplett</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Nur Ordnerstruktur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFS Extraktions-Modus auswählen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Bitte wähle, wie das RomFS gespeichert werden soll.&lt;br&gt;&quot;Full&quot; wird alle Dateien des Spiels extrahieren, während &lt;br&gt;&quot;Skeleton&quot; nur die Ordnerstruktur erstellt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Es ist nicht genügend Speicher (%1) vorhanden um das RomFS zu entpacken. Bitte sorge für genügend Speicherplatze oder wähle ein anderes Verzeichnis aus. (Emulation &gt; Konfiguration &gt; System &gt; Dateisystem &gt; Dump Root)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>RomFS wird extrahiert...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Abbrechen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS wurde extrahiert!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Der Vorgang wurde erfolgreich abgeschlossen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
- <translation type="unfinished"/>
+ <translation>Integritätsüberprüfung konnte nicht durchgeführt werden!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
- <translation type="unfinished"/>
+ <translation>Datei-Inhalte wurden nicht auf Gültigkeit überprüft.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
- <translation type="unfinished"/>
+ <translation>Integritätsüberprüfung fehlgeschlagen!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
- <translation type="unfinished"/>
+ <translation>Datei-Inhalte könnten defekt sein.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
- <translation type="unfinished"/>
+ <translation>Überprüfe Integrität…</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
- <translation type="unfinished"/>
+ <translation>Integritätsüberprüfung erfolgreich!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Verknüpfung erstellen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
- <translation type="unfinished"/>
+ <translation>Dies wird eine Verknüpfung zum aktuellen AppImage erstellen. Dies könnte nicht gut funktionieren falls du aktualisierst. Fortfahren?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>Verknüpfung kann nicht erstellt werden. Pfad &quot;%1&quot; existiert nicht.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Icon erstellen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Symboldatei konnte nicht erstellt werden. Der Pfad &quot;%1&quot; existiert nicht oder kann nicht erstellt werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
- <translation type="unfinished"/>
+ <translation>Starte %1 mit dem yuzu Emulator</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Verknüpfung konnte nicht unter %1 erstellt werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Verknüpfung wurde erfolgreich erstellt unter %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Fehler beim Öffnen von %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Verzeichnis auswählen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Einstellungen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Spiel-Einstellungen konnten nicht geladen werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch-Programme (%1);;Alle Dateien (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Datei laden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Öffne das extrahierte ROM-Verzeichnis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Ungültiges Verzeichnis ausgewählt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Das Verzeichnis, das du ausgewählt hast, enthält keine &apos;main&apos;-Datei.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Installierbares Switch-Programm (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submissions Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Dateien installieren</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n Datei verbleibend</numerusform><numerusform>%n Dateien verbleibend</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Datei &quot;%1&quot; wird installiert...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>NAND-Installation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Um Konflikte zu vermeiden, raten wir Nutzern davon ab, Spiele im NAND zu installieren.
Bitte nutze diese Funktion nur zum Installieren von Updates und DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n file was newly installed
@@ -4360,351 +4362,389 @@ Bitte nutze diese Funktion nur zum Installieren von Updates und DLC.</translatio
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
- <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
+ <translation><numerusform>%n Datei wurde überschrieben
+</numerusform><numerusform>%n Dateien wurden überschrieben
+</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
- <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
+ <translation><numerusform>%n Datei konnte nicht installiert werden
+</numerusform><numerusform>%n Dateien konnten nicht installiert werden
+</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Systemanwendung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Systemarchiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Systemanwendungsupdate</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Firmware-Paket (Typ A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Firmware-Paket (Typ B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Spiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Spiel-Update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Spiel-DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta-Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Wähle den NCA-Installationstyp aus...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Bitte wähle, als was diese NCA installiert werden soll:
(In den meisten Fällen sollte die Standardeinstellung &apos;Spiel&apos; ausreichen.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Installation fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Der Titel-Typ, den du für diese NCA ausgewählt hast, ist ungültig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Datei nicht gefunden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Datei &quot;%1&quot; nicht gefunden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Hardwareanforderungen nicht erfüllt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Dein System erfüllt nicht die empfohlenen Mindestanforderungen der Hardware. Meldung der Komptabilität wurde deaktiviert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Fehlender yuzu-Account</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Um einen Kompatibilitätsbericht abzuschicken, musst du einen yuzu-Account mit yuzu verbinden.&lt;br&gt;&lt;br/&gt;Um einen yuzu-Account zu verbinden, prüfe die Einstellungen unter Emulation &amp;gt; Konfiguration &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Fehler beim Öffnen der URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL &quot;%1&quot; kann nicht geöffnet werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS Aufnahme</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Datei von Spieler 1 überschreiben?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Ungültige Konfiguration erkannt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Handheld-Controller können nicht im Dock verwendet werden. Der Pro-Controller wird verwendet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Das aktuelle Amiibo wurde entfernt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Das aktuelle Spiel sucht nicht nach Amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo-Datei (%1);; Alle Dateien (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Amiibo laden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Fehler beim Laden der Amiibo-Daten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Die ausgewählte Datei ist keine gültige Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Die ausgewählte Datei wird bereits verwendet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Ein unbekannter Fehler ist aufgetreten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
- <translation type="unfinished"/>
+ <translation>Überprüfung für die folgenden Dateien ist fehlgeschlagen:
+
+%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
- <translation type="unfinished"/>
+ <translation>Keine Firmware verfügbar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>Bitte installiere die Firmware um das Album-Applet zu nutzen.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>Album-Applet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>Album-Applet ist nicht verfügbar. Bitte Firmware erneut installieren.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>Bitte installiere die Firmware um das Cabinet-Applet zu nutzen.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Cabinet-Applet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>Cabinet-Applet ist nicht verfügbar. Bitte Firmware erneut installieren.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
- <translation type="unfinished"/>
+ <translation>Bitte installiere die Firmware um den Mii-Editor zu nutzen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
- <translation type="unfinished"/>
+ <translation>Mii-Edit-Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
- <translation type="unfinished"/>
+ <translation>Mii-Editor ist nicht verfügbar. Bitte Firmware erneut installieren.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Screenshot aufnehmen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG Bild (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS Zustand: Läuft %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS Zustand: Aufnahme %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
- <translation type="unfinished"/>
+ <translation>TAS Status: Untätig %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS Zustand: Ungültig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
- <translation type="unfinished"/>
+ <translation>&amp;Stoppe Ausführung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Aufnahme stoppen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>Aufnahme</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skalierung: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Geschwindigkeit: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Geschwindigkeit: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Spiel: %1 FPS (Unbegrenzt)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Spiel: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>KEIN AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>LAUTSTÄRKE: STUMM</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>LAUTSTÄRKE: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Schlüsselableitung bestätigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4717,37 +4757,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
Dieser Prozess wird die generierten Schlüsseldateien löschen und die Schlüsselableitung neu starten.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Fuses fehlen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0 fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Main fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - PRODINFO fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Derivationskomponenten fehlen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Die Verschlüsselungsschlüssel fehlen. &lt;br&gt;Bitte folgen Sie &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;dem Yuzu Schnellstart Guide&lt;/a&gt; um ihre benötigten Schlüssel, Firmware und Spiele zu erhalten.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4755,49 +4795,49 @@ on your system&apos;s performance.</source>
Dies könnte, je nach Leistung deines Systems, bis zu einer Minute dauern.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Schlüsselableitung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Die Systemarchiventschlüsselung ist gescheitert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
- <translation type="unfinished"/>
+ <translation>Verschlüsselungsschlüssel konnten die Firmware nicht entschlüsseln. &lt;br&gt;Bitte befolge &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;den yuzu-Quickstart-Guide&lt;/a&gt; um alle deine Schlüssel (Keys), Firmware, und Spiele zu erhalten.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>RomFS wählen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Wähle, welches RomFS du speichern möchtest.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Bist du sicher, dass du yuzu beenden willst?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Bist du sicher, dass du die Emulation stoppen willst? Jeder nicht gespeicherte Fortschritt geht verloren.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4823,7 +4863,7 @@ Möchtest du dies umgehen und sie trotzdem beenden?</translation>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Nearest</source>
- <translation type="unfinished"/>
+ <translation>Nächster</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
@@ -4883,22 +4923,22 @@ Möchtest du dies umgehen und sie trotzdem beenden?</translation>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="103"/>
<source>Null</source>
- <translation type="unfinished"/>
+ <translation>Null</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="107"/>
<source>GLSL</source>
- <translation type="unfinished"/>
+ <translation>GLSL</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="108"/>
<source>GLASM</source>
- <translation type="unfinished"/>
+ <translation>GLASM</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="109"/>
<source>SPIRV</source>
- <translation type="unfinished"/>
+ <translation>SPIRV</translation>
</message>
</context>
<context>
@@ -4949,241 +4989,251 @@ Möchtest du dies umgehen und sie trotzdem beenden?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Favorit</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Spiel starten</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Spiel ohne benutzerdefinierte Spiel-Einstellungen starten</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Spielstand-Verzeichnis öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Mod-Verzeichnis öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
- <translation type="unfinished"/>
+ <translation>Transferierbaren Pipeline-Cache öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Installiertes Update entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Alle installierten DLCs entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Spiel-Einstellungen entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>Spielzeit-Daten entfernen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Cache-Speicher entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>OpenGL-Pipeline-Cache entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Vulkan-Pipeline-Cache entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Alle Pipeline-Caches entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Alle installierten Inhalte entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>RomFS speichern</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>RomFS nach SDMC dumpen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
- <translation type="unfinished"/>
+ <translation>Integrität überprüfen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Title-ID in die Zwischenablage kopieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>GameDB-Eintrag öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Verknüpfung erstellen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Zum Desktop hinzufügen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Zum Menü &quot;Anwendungen&quot; hinzufügen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Eigenschaften</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Unterordner scannen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Spieleverzeichnis entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Nach Oben</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Nach Unten</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Verzeichnis öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Löschen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Name</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatibilität</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Add-ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Dateityp</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Größe</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>Spielzeit</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Im Spiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
- <translation type="unfinished"/>
+ <translation>Spiel startet, stürzt jedoch ab oder hat signifikante Glitches, die es verbieten es durchzuspielen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Das Spiel kann ohne Probleme gespielt werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Spielbar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Das Spiel funktioniert mit minimalen grafischen oder Tonstörungen und ist komplett spielbar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Menü</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Das Spiel lädt, ist jedoch nicht im Stande den Startbildschirm zu passieren.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Startet nicht</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Das Spiel stürzt beim Versuch zu starten ab.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Nicht getestet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Spiel wurde noch nicht getestet.</translation>
</message>
@@ -5191,7 +5241,7 @@ Möchtest du dies umgehen und sie trotzdem beenden?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Doppelklicke, um einen neuen Ordner zur Spieleliste hinzuzufügen.</translation>
</message>
@@ -5204,12 +5254,12 @@ Möchtest du dies umgehen und sie trotzdem beenden?</translation>
<translation><numerusform>%1 von %n Ergebnis</numerusform><numerusform>%1 von %n Ergebnisse(n)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filter:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Wörter zum Filtern eingeben</translation>
</message>
@@ -5293,7 +5343,8 @@ Möchtest du dies umgehen und sie trotzdem beenden?</translation>
<location filename="../../src/yuzu/multiplayer/host_room.cpp" line="186"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>Ankündigen des Raums in der öffentlichen Lobby fehlgeschlagen. Um einen öffentlichen Raum zu erstellen, muss ein gültiges yuzu-Konto in Emulation -&gt; Konfigurieren -&gt; Web hinterlegt sein. Falls der Raum nicht in der öffentlichen Lobby angezeigt werden soll, wähle &quot;Nicht gelistet&quot;.
+Debug Nachricht:</translation>
</message>
</context>
<context>
@@ -5326,6 +5377,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Hauptfenster</translation>
</message>
@@ -5352,7 +5404,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="123"/>
<source>Change Docked Mode</source>
- <translation type="unfinished"/>
+ <translation>Dockmodus ändern</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="124"/>
@@ -5431,6 +5483,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Statusleiste umschalten</translation>
</message>
@@ -5668,186 +5725,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Hilfe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Dateien im NAND installieren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>Datei &amp;laden...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>&amp;Verzeichnis laden...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>S&amp;chließen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Stop</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Schlüssel neu initialisieren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>Installierte Inhalte &amp;überprüfen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Über yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>&amp;Einzelfenster-Modus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Kon&amp;figurieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>D&amp;ock-Widget-Header anzeigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>&amp;Filterleiste anzeigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>&amp;Statusleiste anzeigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Statusleiste anzeigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Öffentliche Spiele-Lobbys durchsuchen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Raum erstellen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Raum verlassen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Direkte Verbindung zum Raum</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Aktuellen Raum anzeigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>Vollbild (&amp;u)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>Neusta&amp;rt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>&amp;Amiibo laden/entfernen...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Kompatibilität melden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>&amp;Mods-Seite öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>&amp;Schnellstart-Anleitung öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>&amp;yuzu-Verzeichnis öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Bildschirmfoto aufnehmen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>&amp;Album öffnen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>Spitzname und Besitzer &amp;festlegen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>Spiel-Daten &amp;löschen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>Amiibo &amp;wiederherstellen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>Amiibo &amp;formatieren</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
- <translation type="unfinished"/>
+ <translation>&amp;Mii-Editor öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;TAS &amp;konfigurieren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>&amp;Spiel-Einstellungen ändern...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Zurücksetzen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>Aufnahme</translation>
</message>
@@ -5945,7 +6032,8 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="208"/>
<source>Failed to update the room information. Please check your Internet connection and try hosting the room again.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>Aktualisieren der Rauminformationen fehlgeschlagen. Überprüfe deine Internetverbindung und versuche erneut einen Raum zu erstellen.
+Debug Message:</translation>
</message>
</context>
<context>
@@ -5978,7 +6066,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
<source>You must choose a Preferred Game to host a room. If you do not have any games in your game list yet, add a game folder by clicking on the plus icon in the game list.</source>
- <translation type="unfinished"/>
+ <translation>Es muss ein bevorzugtes Spiel ausgewählt werden um einen Raum zu erstellen. Sollten keine Spiele in der Spieleliste vorhanden sein, kann ein Spielordner mittels des Plus-Symbols in der Spieleliste hinzugefügt werden.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
@@ -6010,7 +6098,7 @@ Wenn Sie immer noch keine Verbindung herstellen können, wenden Sie sich an den
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
<source>Version mismatch! Please update to the latest version of yuzu. If the problem persists, contact the room host and ask them to update the server.</source>
- <translation type="unfinished"/>
+ <translation>Keine Übereinstimmung der Versionen! Bitte zur neuesten Version von yuzu aktualisieren. Sollte das Problem weiterhin vorhanden sein, kontaktiere den Raumersteller und bitte ihn den Server zu aktualisieren.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
@@ -6155,27 +6243,27 @@ p, li { white-space: pre-wrap; }
<translation>Spielt kein Spiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Installierte SD-Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Installierte NAND-Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Systemtitel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Neues Spieleverzeichnis hinzufügen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoriten</translation>
</message>
@@ -6412,7 +6500,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="416"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="440"/>
<source>%1%2Hat %3</source>
- <translation type="unfinished"/>
+ <translation>%1%2Hat %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="420"/>
@@ -6531,25 +6619,25 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
<source>%1%2%3%4</source>
- <translation type="unfinished"/>
+ <translation>%1%2%3%4</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="231"/>
<source>%1%2%3Hat %4</source>
- <translation type="unfinished"/>
+ <translation>%1%2%3Hat %4</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
<source>%1%2%3Axis %4</source>
- <translation type="unfinished"/>
+ <translation>%1%2%3Achse %4</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="240"/>
<source>%1%2%3Button %4</source>
- <translation type="unfinished"/>
+ <translation>%1%2%3Knopf %4</translation>
</message>
</context>
<context>
@@ -6701,7 +6789,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro-Controller</translation>
</message>
@@ -6714,7 +6802,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Zwei Joycons</translation>
</message>
@@ -6727,7 +6815,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Linker Joycon</translation>
</message>
@@ -6740,7 +6828,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Rechter Joycon</translation>
</message>
@@ -6769,7 +6857,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
@@ -6885,32 +6973,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>Nicht genügend Controller</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube-Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke-Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64 Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
@@ -7031,7 +7124,7 @@ Bitte versuche es noch einmal oder kontaktiere den Entwickler der Software.</tra
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="222"/>
<source>Send save data for which user?</source>
- <translation type="unfinished"/>
+ <translation>Speicherdaten für welchen Nutzer senden?</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="226"/>
@@ -7097,7 +7190,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="158"/>
<source>[%1] %2</source>
- <translation type="unfinished"/>
+ <translation>[%1] %2</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="184"/>
diff --git a/dist/languages/el.ts b/dist/languages/el.ts
index cb6cb9c9a..d421be61d 100644
--- a/dist/languages/el.ts
+++ b/dist/languages/el.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -882,49 +882,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Δημιουργία Minidump μετά από κατάρρευση</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Αυτό θα μηδενιστεί αυτόματα όταν το yuzu κλείσει.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Απαιτείται επανεκκίνηση</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>το yuzu πρέπει να επανεκκινηθεί για να εφαρμοστεί αυτή η ρύθμιση.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Το web applet δεν έχει συσταθεί</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Δημιουργία MiniDump που δεν έχει συσταθεί</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1343,7 +1323,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Αντικρουόμενη Ακολουθία Πλήκτρων</translation>
</message>
@@ -1364,27 +1344,37 @@ This would ban both their forum username and their IP address.</source>
<translation>Μη Έγκυρο</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Επαναφορά Προκαθορισμένων</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Καθαρισμός</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Αντικρουόμενη Ακολουθία Κουμπιών</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Η προεπιλεγμένη ακολουθία κουμπιών έχει ήδη αντιστοιχιστεί στο: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Η προεπιλεγμένη ακολουθία πλήκτρων έχει ήδη αντιστοιχιστεί στο: %1</translation>
</message>
@@ -3359,67 +3349,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Στιγμιότυπα</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Ανάλυση:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3737,120 +3732,120 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Τηλεμετρία</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Πόσα καρέ ανά δευτερόλεπτο εμφανίζει το παιχνίδι αυτή τη στιγμή. Αυτό διαφέρει από παιχνίδι σε παιχνίδι και από σκηνή σε σκηνή.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Συνέχεια</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Παύση</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Μη μεταφρασμένη συμβολοσειρά
@@ -3858,843 +3853,879 @@ Drag points to change position, or double-click table cells to edit values.</sou
Για μια εξήγηση των διαφόρων μορφών Switch που υποστηρίζει το yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt; δείτε το wiki μας &lt;/a&gt;. Αυτό το μήνυμα δεν θα εμφανιστεί ξανά.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Σφάλμα κατά τη φόρτωση της ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Εμφανίστηκε ένα απροσδιόριστο σφάλμα. Ανατρέξτε στο αρχείο καταγραφής για περισσότερες λεπτομέρειες.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Αποθήκευση δεδομένων</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Ο φάκελος δεν υπάρχει!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Αφαίρεση Αρχείου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Επιλογή λειτουργίας απόρριψης RomFS </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Μη αποθηκευμένη μετάφραση.
Παρακαλούμε επιλέξτε τον τρόπο με τον οποίο θα θέλατε να γίνει η απόρριψη της RomFS.&lt;br&gt;
Η επιλογή Πλήρης θα αντιγράψει όλα τα αρχεία στο νέο κατάλογο, ενώ η επιλογή &lt;br&gt; Σκελετός θα δημιουργήσει μόνο τη δομή του καταλόγου.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Ακύρωση</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Η επέμβαση ολοκληρώθηκε με επιτυχία.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Επιλογή καταλόγου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Ιδιότητες</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Φόρτωση αρχείου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Αποτελέσματα εγκατάστασης</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Εφαρμογή συστήματος</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Παιχνίδι</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Ενημέρωση παιχνιδιού</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC παιχνιδιού</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Επιλέξτε τον τύπο εγκατάστασης NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Το αρχείο δεν βρέθηκε</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Το αρχείο &quot;%1&quot; δεν βρέθηκε</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Σφάλμα κατα το άνοιγμα του URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Αδυναμία ανοίγματος του URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Σφάλμα</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Φόρτωση Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Σφάλμα φόρτωσης δεδομένων Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Το επιλεγμένο αρχείο δεν αποτελεί έγκυρο amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Το επιλεγμένο αρχείο χρησιμοποιείται ήδη</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Λήψη στιγμιότυπου οθόνης</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Εικόνα PBG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Έναρξη</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Κλίμακα: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Ταχύτητα: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Ταχύτητα: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Καρέ: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4705,86 +4736,86 @@ This will delete your autogenerated key files and re-run the key derivation modu
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Λείπει το BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Λείπει το BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- Λείπει το PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Είστε σίγουροι ότι θέλετε να κλείσετε το yuzu;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4934,241 +4965,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Αγαπημένο</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Έναρξη παιχνιδιού</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Άνοιγμα Τοποθεσίας Αποθήκευσης Δεδομένων</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Άνοιγμα Τοποθεσίας Δεδομένων Mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Αφαίρεση</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Αφαίρεση Εγκατεστημένης Ενημέρωσης</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Αφαίρεση Όλων των Εγκατεστημένων DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Καταργήστε Όλη την Κρυφή μνήμη του Pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Καταργήστε Όλο το Εγκατεστημένο Περιεχόμενο</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Απόθεση του RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Απόθεση του RomFS στο SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Αντιγραφή του Title ID στο Πρόχειρο</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Μεταβείτε στην καταχώρηση GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Ιδιότητες</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Σκανάρισμα Υποφακέλων</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Αφαίρεση Φακέλου Παιχνιδιών</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Μετακίνηση Επάνω</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Μετακίνηση Κάτω</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Ανοίξτε την Τοποθεσία Καταλόγου</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Καθαρισμός</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Όνομα</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Συμβατότητα</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Πρόσθετα</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Τύπος αρχείου</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Μέγεθος</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Τέλεια</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Εισαγωγή/Μενου</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Δεν ξεκινά</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Το παιχνίδι διακόπτεται κατά την προσπάθεια εκκίνησης.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Μη Τεσταρισμένο</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Το παιχνίδι δεν έχει ακόμα τεσταριστεί.</translation>
</message>
@@ -5176,7 +5217,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Διπλο-κλικ για προσθήκη νεου φακέλου στη λίστα παιχνιδιών</translation>
</message>
@@ -5189,12 +5230,12 @@ Would you like to bypass this and exit anyway?</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Φίλτρο:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Εισαγάγετε μοτίβο για φιλτράρισμα</translation>
</message>
@@ -5311,6 +5352,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
@@ -5416,6 +5458,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5653,186 +5700,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Παύση</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Σταμάτημα </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Περιήγηση σε δημόσιο λόμπι παιχνιδιού</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Δημιουργία δωματίου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Αποχωρήσει από το δωμάτιο</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Άμεση σύνδεση σε Δωμάτιο</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Εμφάνιση τρέχοντος δωματίου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Έναρξη</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
@@ -6135,27 +6212,27 @@ p, li { white-space: pre-wrap; }
<translation>Δεν παίζει παιχνίδι</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Τίτλοι Συστήματος</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Προσθήκη Νέας Τοποθεσίας Παιχνιδιών</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Αγαπημένα</translation>
</message>
@@ -6681,7 +6758,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6694,7 +6771,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Διπλά Joycons</translation>
</message>
@@ -6707,7 +6784,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Αριστερό Joycon</translation>
</message>
@@ -6720,7 +6797,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Δεξί Joycon</translation>
</message>
@@ -6749,7 +6826,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
@@ -6865,32 +6942,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Χειριστήριο GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Χειριστήριο NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Χειριστήριο SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Χειριστήριο N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/es.ts b/dist/languages/es.ts
index 608f9b399..4adeb599f 100644
--- a/dist/languages/es.ts
+++ b/dist/languages/es.ts
@@ -277,7 +277,7 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="183"/>
<source>No The game crashes or freezes during gameplay</source>
- <translation>No El juego se bloquea o se congela durante el juego</translation>
+ <translation>No El juego se bloquea o se congela durante la ejecución</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="195"/>
@@ -312,7 +312,7 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="294"/>
<source>None Everything is rendered as it looks on the Nintendo Switch</source>
- <translation>Ninguno Todo está renderizado conforme se ve en la Nintendo Switch</translation>
+ <translation>Ninguno Todo está renderizado conforme se muestra en la Nintendo Switch</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="306"/>
@@ -322,22 +322,22 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="339"/>
<source>Major The game has major audio errors</source>
- <translation>Importantes El juego tiene grandes problemas de sonido</translation>
+ <translation>Importantes El juego tiene bastantes problemas de audio</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="346"/>
<source>Minor The game has minor audio errors</source>
- <translation>Menores El juego tiene pequeños problemas de sonido</translation>
+ <translation>Menores El juego tiene pequeños problemas de audio</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="353"/>
<source>None Audio is played perfectly</source>
- <translation>Ninguno El sonido se reproduce perfectamente</translation>
+ <translation>Ninguno El audio se reproduce perfectamente</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="365"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Does the game have any audio glitches / missing effects?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;¿El juego tiene algún problema de sonido o falta de algunos efectos?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;¿El juego tiene algún problema de audio o falta de efectos de sonido?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="389"/>
@@ -352,7 +352,7 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/compatdb.cpp" line="195"/>
<source>Communication error</source>
- <translation>Error de comunicación.</translation>
+ <translation>Error de comunicación</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.cpp" line="196"/>
@@ -373,13 +373,13 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Auto (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Predeterminada (%1)</translation>
@@ -893,49 +893,29 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Crear mini volcado tras un crash</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Activa esta opción para mostrar en la consola la última lista de comandos de audio generada. Solo afecta a los juegos que utilizan el renderizador de audio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Volcar comandos de audio a la consola**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Activar servicios de reporte detallados**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Esto se reiniciará automáticamente cuando yuzu se cierre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Reinicio requerido</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>Para aplicar estos ajustes es necesario reiniciar yuzu.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>La web applet no se ha compilado</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>La creación del mini volcado no se ha compilado</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -984,7 +964,7 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure.ui" line="67"/>
<source>Some settings are only available when a game is not running.</source>
- <translation>Algunos ajustes sólo están disponibles cuando no se esté ejecutando ningún juego.</translation>
+ <translation>Algunos ajustes sólo están disponibles cuando no se estén ejecutando los juegos.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="62"/>
@@ -1354,7 +1334,7 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Combinación de teclas en conflicto</translation>
</message>
@@ -1375,27 +1355,37 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<translation>No válido</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>Configuración de teclas de atajo no válida</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation>Ha ocurrido un error. Por favor, repórtelo en Github.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Restaurar valor predeterminado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Eliminar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Secuencia de botones en conflicto</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>La secuencia de botones por defecto ya esta asignada a: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>La combinación de teclas predeterminada ya ha sido asignada a: %1</translation>
</message>
@@ -2670,7 +2660,7 @@ Los valores actuales son %1% y %2% respectivamente.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="240"/>
<source>Some settings are only available when a game is not running.</source>
- <translation>Algunos ajustes sólo están disponibles cuando no se esté ejecutando ningún juego.</translation>
+ <translation>Algunos ajustes sólo están disponibles cuando no se estén ejecutando los juegos.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="68"/>
@@ -2786,7 +2776,7 @@ Los valores actuales son %1% y %2% respectivamente.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="168"/>
<source>Profile management is available only when game is not running.</source>
- <translation>El sistema de perfiles sólo se encuentra disponible cuando no se esté ejecutando ningún juego.</translation>
+ <translation>El sistema de perfiles sólo se encuentra disponible cuando no se estén ejecutando los juegos.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="55"/>
@@ -3373,67 +3363,72 @@ Arrastra los puntos para cambiar de posición, o haz doble clic en las celdas de
<translation>Mostrar columna de tipos de archivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>Mostrar columna de tiempo de juego</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Tamaño de los iconos de los juegos:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Tamaño de los iconos de la carpeta:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Texto de fila 1:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Texto de fila 2:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Capturas de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Preguntar dónde guardar las capturas de pantalla (sólo en Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Ruta de las capturas de pantalla:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>TextLabel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Resolución:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Selecciona la ruta de las capturas de pantalla:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Auto (%1 x %2, %3 x %4)</translation>
@@ -3751,612 +3746,616 @@ Arrastra los puntos para cambiar de posición, o haz doble clic en las celdas de
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Los datos de uso anónimos se recogen&lt;/a&gt; para ayudar a mejorar yuzu. &lt;br/&gt;&lt;br/&gt;¿Deseas compartir tus datos de uso con nosotros?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetría </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Se ha detectado una instalación corrupta de Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>La inicialización de Vulkan ha fallado durante la ejecución. Haz clic &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;aquí para más información sobre como arreglar el problema&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Ejecutando un juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Cargando Web applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Desactivar Web applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Deshabilitar el Applet Web puede causar comportamientos imprevistos y debería solo ser usado con Super Mario 3D All-Stars. ¿Estas seguro que quieres deshabilitar el Applet Web?
(Puede ser reactivado en las configuraciones de Depuración.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>La cantidad de shaders que se están construyendo actualmente</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>El multiplicador de escala de resolución seleccionado actualmente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>La velocidad de emulación actual. Los valores superiores o inferiores al 100% indican que la emulación se está ejecutando más rápido o más lento que en una Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>La cantidad de fotogramas por segundo que se está mostrando el juego actualmente. Esto variará de un juego a otro y de una escena a otra.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tiempo que lleva emular un fotograma de la Switch, sin tener en cuenta la limitación de fotogramas o sincronización vertical. Para una emulación óptima, este valor debería ser como máximo de 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Desmutear</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Mutear</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Restablecer Volumen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Eliminar archivos recientes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>El ratón emulado está activado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>La entrada de un ratón real y la panoramización del ratón son incompatibles. Por favor, desactive el ratón emulado en la configuración avanzada de entrada para permitir así la panoramización del ratón.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Advertencia: formato del juego obsoleto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Está utilizando el formato de directorio de ROM deconstruido para este juego, que es un formato desactualizado que ha sido reemplazado por otros, como los NCA, NAX, XCI o NSP. Los directorios de ROM deconstruidos carecen de íconos, metadatos y soporte de actualizaciones.&lt;br&gt;&lt;br&gt;Para ver una explicación de los diversos formatos de Switch que soporta yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;echa un vistazo a nuestra wiki&lt;/a&gt;. Este mensaje no se volverá a mostrar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>¡Error al cargar la ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>El formato de la ROM no es compatible.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Se ha producido un error al inicializar el núcleo de video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu ha encontrado un error al ejecutar el núcleo de video. Esto suele ocurrir al no tener los controladores de la GPU actualizados, incluyendo los integrados. Por favor, revisa el registro para más detalles. Para más información sobre cómo acceder al registro, por favor, consulta la siguiente página: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Como cargar el archivo de registro&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>¡Error al cargar la ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Por favor, sigue &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guía de inicio rápido de yuzu&lt;/a&gt; para revolcar los archivos.&lt;br&gt;Puedes consultar la wiki de yuzu&lt;/a&gt; o el Discord de yuzu&lt;/a&gt; para obtener ayuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Error desconocido. Por favor, consulte el archivo de registro para ver más detalles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Cerrando software...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Datos de guardado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Datos de mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Error al abrir la carpeta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>¡La carpeta no existe!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Error al abrir el caché transferible de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>No se pudo crear el directorio de la caché de los shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Error al eliminar el contenido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Error al eliminar la actualización</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Error al eliminar el DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>¿Eliminar contenido del juego instalado?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>¿Eliminar actualización del juego instalado?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>¿Eliminar el DLC del juego instalado?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Eliminar entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Se ha eliminado con éxito</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Se ha eliminado con éxito el juego base instalado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>El juego base no está instalado en el NAND y no se puede eliminar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Se ha eliminado con éxito la actualización instalada.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>No hay ninguna actualización instalada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>No hay ningún DLC instalado para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Se ha eliminado con éxito %1 DLC instalado(s).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>¿Deseas eliminar el caché transferible de shaders de OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>¿Deseas eliminar el caché transferible de shaders de Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>¿Deseas eliminar todo el caché transferible de shaders?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>¿Deseas eliminar la configuración personalizada del juego?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>¿Quitar almacenamiento de caché?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Eliminar archivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>Eliminar información del tiempo de juego</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>¿Reestablecer tiempo de juego?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Error al eliminar la caché de shaders transferibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>No existe caché de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>El caché de shaders transferibles se ha eliminado con éxito.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>No se ha podido eliminar la caché de shaders transferibles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Error al eliminar la caché de canalización del controlador Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>No se ha podido eliminar la caché de canalización del controlador.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Error al eliminar las cachés de shaders transferibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Cachés de shaders transferibles eliminadas con éxito.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>No se ha podido eliminar el directorio de cachés de shaders transferibles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Error al eliminar la configuración personalizada del juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>No existe una configuración personalizada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Se eliminó con éxito la configuración personalizada del juego.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>No se ha podido eliminar la configuración personalizada del juego.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>¡La extracción de RomFS ha fallado!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Se ha producido un error al copiar los archivos RomFS o el usuario ha cancelado la operación.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Completo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>En secciones</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Elegir método de volcado de RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Por favor, selecciona el método en que quieres volcar el RomFS.&lt;br&gt;Completo copiará todos los archivos al nuevo directorio &lt;br&gt; mientras que en secciones solo creará la estructura del directorio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>No hay suficiente espacio en %1 para extraer el RomFS. Por favor, libera espacio o elige otro directorio de volcado en Emulación &gt; Configuración &gt; Sistema &gt; Sistema de archivos &gt; Raíz de volcado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Extrayendo RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>¡La extracción RomFS ha tenido éxito!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>La operación se completó con éxito.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>¡No se pudo ejecutar la verificación de integridad!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>No se ha podido comprobar la validez de los contenidos del archivo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>¡Verificación de integridad fallida!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>Los contenidos del archivo pueden estar corruptos.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>Verificando integridad...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>¡La verificación de integridad ha sido un éxito!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Crear acceso directo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Esto creará un acceso directo a la AppImage actual. Esto puede no funcionar bien si se actualiza. ¿Continuar?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>No se puede crear un acceso directo en el escritorio. La ruta &quot;%1&quot; no existe.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>No se puede crear un acceso directo en el menú de aplicaciones. La ruta &quot;%1&quot; no existe y no se puede crear.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>No se puede crear un acceso directo. La ruta &quot;%1&quot; no existe.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Crear icono</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>No se puede crear el archivo de icono. La ruta &quot;%1&quot; no existe y no se ha podido crear.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Iniciar %1 con el Emulador yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Error al crear un acceso directo en %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Se ha creado un acceso directo a %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Error al intentar abrir %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Seleccionar directorio</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Propiedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>No se pueden cargar las propiedades del juego.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Ejecutable de Switch (%1);;Todos los archivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Cargar archivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Abrir el directorio de la ROM extraída</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Directorio seleccionado no válido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>El directorio que ha seleccionado no contiene ningún archivo &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Archivo de Switch Instalable (*.nca *.nsp *.xci);;Archivo de contenidos de Nintendo (*.nca);;Paquete de envío de Nintendo (*.nsp);;Imagen de cartucho NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Instalar archivos</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n archivo(s) restantes</numerusform><numerusform>%n archivo(s) restantes</numerusform><numerusform>%n archivo(s) restantes</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalando el archivo &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Instalar resultados</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Para evitar posibles conflictos, no se recomienda a los usuarios que instalen juegos base en el NAND.
Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n archivo(s) recién instalado/s
@@ -4365,7 +4364,7 @@ Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</tr
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n archivo(s) recién sobreescrito/s
@@ -4374,7 +4373,7 @@ Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</tr
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n archivo(s) no se instaló/instalaron
@@ -4383,194 +4382,194 @@ Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</tr
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Aplicación del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Archivo del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Actualización de la aplicación del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Paquete de firmware (Tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Paquete de firmware (Tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Actualización de juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC del juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Titulo delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Seleccione el tipo de instalación NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Seleccione el tipo de título en el que deseas instalar este NCA como:
(En la mayoría de los casos, el &apos;Juego&apos; predeterminado está bien).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Fallo en la instalación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>El tipo de título que seleccionó para el NCA no es válido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Archivo no encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Archivo &quot;%1&quot; no encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>Aceptar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>No se cumplen los requisitos de hardware</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>El sistema no cumple con los requisitos de hardware recomendados. Los informes de compatibilidad se han desactivado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Falta la cuenta de Yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Para enviar un caso de prueba de compatibilidad de juegos, debes vincular tu cuenta de yuzu.&lt;br&gt;&lt;br/&gt; Para vincular tu cuenta de yuzu, ve a Emulación &amp;gt; Configuración &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Error al abrir la URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>No se puede abrir la URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Grabación TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>¿Sobrescribir archivo del jugador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Configuración no válida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>El controlador del modo portátil no puede ser usado en el modo sobremesa. Se seleccionará el controlador Pro en su lugar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>El amiibo actual ha sido eliminado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>El juego actual no está buscando amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Archivo amiibo (%1);; Todos los archivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Cargar amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Error al cargar los datos Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>El archivo seleccionado no es un amiibo válido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>El archivo seleccionado ya se encuentra en uso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Ha ocurrido un error inesperado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4579,145 +4578,177 @@ Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</tr
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
- <translation type="unfinished"/>
+ <translation>No hay firmware disponible</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>Por favor, instala el firmware para usar la aplicación del Álbum.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>Applet de Álbum</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>La aplicación del Álbum no esta disponible. Por favor, reinstala el firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>Por favor, instala el firmware para usar la applet de Cabinet.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Applet de Cabinet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>La applet de Cabinet no está disponible. Por favor, reinstale el firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
- <translation type="unfinished"/>
+ <translation>Por favor, instala el firmware para usar el editor de Mii.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
- <translation type="unfinished"/>
+ <translation>Applet de Editor de Mii</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
- <translation type="unfinished"/>
+ <translation>El editor de Mii no está disponible. Por favor, reinstala el firmware.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Imagen PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Estado TAS: ejecutando %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Estado TAS: grabando %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Estado TAS: inactivo %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Estado TAS: nulo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar de ejecutar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Pausar g&amp;rabación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>G&amp;rabar</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Creando: %n shader(s)</numerusform><numerusform>Construyendo: %n shader(s)</numerusform><numerusform>Construyendo: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escalado: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Velocidad: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Velocidad: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Juego: %1 FPS (desbloqueado)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Juego: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Fotogramas: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUMEN: SILENCIO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>VOLUMEN: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmar la clave de rederivación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4734,37 +4765,37 @@ es lo que quieres hacer si es necesario.
Esto eliminará los archivos de las claves generadas automáticamente y volverá a ejecutar el módulo de derivación de claves.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Faltan fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Falta BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Falta BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Falta PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Faltan componentes de derivación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Faltan las claves de encriptación. &lt;br&gt;Por favor, sigue &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guía rápida de yuzu&lt;/a&gt; para obtener todas tus claves, firmware y juegos.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4773,49 +4804,49 @@ Esto puede llevar unos minutos dependiendo
del rendimiento de su sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Obtención de claves</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Desencriptación del Sistema de Archivos Fallida</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Las claves de encriptación no han podido desencriptar el firmware. &lt;br&gt;Por favor, siga&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guía de inicio rápido de yuzu&lt;/a&gt; para obtener todas tus claves, firmware y juegos.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Selecciona el destinatario para volcar el RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Por favor, seleccione los RomFS que deseas volcar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>¿Estás seguro de que quieres cerrar yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>¿Estás seguro de que quieres detener la emulación? Cualquier progreso no guardado se perderá.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4967,241 +4998,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Favorito</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Iniciar juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Iniciar juego sin la configuración personalizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Abrir ubicación de los archivos de guardado</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Abrir ubicación de los mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Abrir caché de canalización de shaders transferibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Eliminar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Eliminar la actualización instalada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Eliminar todos los DLC instalados</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Eliminar la configuración personalizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>Eliminar información del tiempo de juego</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Quitar almacenamiento de caché</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Eliminar caché de canalización de OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Eliminar caché de canalización de Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Eliminar todas las cachés de canalización</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Eliminar todo el contenido instalado</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Volcar RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Volcar RomFS a SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Verificar Integridad</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Copiar la ID del título al portapapeles</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Ir a la sección de bases de datos del juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Crear Acceso directo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Añadir al Escritorio</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Añadir al menú de Aplicaciones</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Propiedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Escanear subdirectorios</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Eliminar directorio de juegos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Mover hacia arriba</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Mover hacia abajo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Abrir ubicación del directorio</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Limpiar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nombre</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Compatibilidad</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Extras/Add-ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Tipo de archivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Tamaño</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>Tiempo de juego</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Inicia</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>El juego se inicia, pero se bloquea o se producen fallos importantes que impiden completarlo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfecta</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>El juego se puede jugar sin problemas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Jugable</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>El juego funciona con pequeños errores gráficos o de sonido y es jugable de principio a fin.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Inicio/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>El juego se ejecuta, pero no puede pasar de la pantalla de inicio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>No funciona</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>El juego se bloquea al intentar iniciar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Sin testear</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>El juego todavía no ha sido testeado todavía.</translation>
</message>
@@ -5209,7 +5250,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Haz doble clic para agregar un nuevo directorio a la lista de juegos.</translation>
</message>
@@ -5222,12 +5263,12 @@ Would you like to bypass this and exit anyway?</source>
<translation><numerusform>%1 de %n resultado(s)</numerusform><numerusform>%1 de %n resultado(s)</numerusform><numerusform>%1 de %n resultado(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Búsqueda:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Introduce un patrón para buscar</translation>
</message>
@@ -5345,6 +5386,7 @@ Mensaje de depuración: </translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Ventana principal</translation>
</message>
@@ -5450,6 +5492,11 @@ Mensaje de depuración: </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation>Alternar Captura de Renderdoc</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Alternar barra de estado</translation>
</message>
@@ -5688,186 +5735,216 @@ Mensaje de depuración: </translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Ayuda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Instalar archivos en NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>C&amp;argar archivo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Cargar &amp;carpeta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>S&amp;alir</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Detener</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Reiniciar claves...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>&amp;Verificar contenidos instalados</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Acerca de yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Modo &amp;ventana</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Con&amp;figurar...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Mostrar complementos de cabecera del D&amp;ock </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Mostrar barra de &amp;búsqueda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Mostrar barra de &amp;estado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Mostrar barra de estado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Buscar en el lobby de juegos públicos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Crear sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Abandonar sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Conexión directa a una sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Mostrar sala actual</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>P&amp;antalla completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Reiniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Cargar/Eliminar &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Reporte de compatibilidad</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Abrir página de &amp;mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Abrir guía de &amp;inicio rápido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;Preguntas frecuentes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Abrir la carpeta de &amp;yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>Abrir &amp;Álbum</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>&amp;Darle Nombre y Propietario</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>&amp;Borrar Datos de Juego</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>&amp;Restaurar Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>&amp;Formatear Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
- <translation type="unfinished"/>
+ <translation>Abrir Editor de &amp;Mii</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Configurar TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Configurar j&amp;uego actual...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Reiniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>G&amp;rabar</translation>
</message>
@@ -6044,7 +6121,7 @@ Mensaje de depuración: </translation>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
<source>Connection to room lost. Try to reconnect.</source>
- <translation>Conexión a la sala perdida. Intenta reconectarte.</translation>
+ <translation>Conexión a la sala perdida. Prueba a reconectarte.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
@@ -6175,27 +6252,27 @@ p, li { white-space: pre-wrap; }
<translation>No jugando ningún juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Títulos instalados en la SD</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Títulos instalados en NAND</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Títulos del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Añadir un nuevo directorio de juegos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoritos</translation>
</message>
@@ -6662,7 +6739,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="192"/>
<source>No game data present</source>
- <translation>No hay datos del juego</translation>
+ <translation>No existen datos de juego</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="232"/>
@@ -6721,7 +6798,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Controlador Pro</translation>
</message>
@@ -6734,7 +6811,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Joycons duales</translation>
</message>
@@ -6747,7 +6824,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon izquierdo</translation>
</message>
@@ -6760,7 +6837,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon derecho</translation>
</message>
@@ -6789,7 +6866,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Portátil</translation>
</message>
@@ -6905,32 +6982,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>No hay suficientes controladores.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Controlador de GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Control de NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Control de SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Control de N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
@@ -7041,7 +7123,7 @@ Por favor, inténtalo de nuevo o contacta con el desarrollador del software.</tr
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="216"/>
<source>Format data for which user?</source>
- <translation>¿Para qué usuario se borrarán sus datos?</translation>
+ <translation>¿Para qué usuario se borrarán los datos?</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="219"/>
diff --git a/dist/languages/fr.ts b/dist/languages/fr.ts
index 91025e950..8b8442037 100644
--- a/dist/languages/fr.ts
+++ b/dist/languages/fr.ts
@@ -36,7 +36,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Site Web&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Code Source &lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributeurs&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Licence&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Site Web&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Code Source&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributeurs&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Licence&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
@@ -374,13 +374,13 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Auto (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Par défaut (%1)</translation>
@@ -430,7 +430,7 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
<source>Click to preview</source>
- <translation>Cliquez pour prévisualiser</translation>
+ <translation>Cliquer pour prévisualiser</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
@@ -730,7 +730,7 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="216"/>
<source>Enable Extended Logging**</source>
- <translation>Activer la Journalisation Étendue**</translation>
+ <translation>Activer la journalisation étendue**</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="223"/>
@@ -830,7 +830,7 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="370"/>
<source>Dump Game Shaders</source>
- <translation>Récupérer Shaders Jeu</translation>
+ <translation>Extraire les shaders du jeu</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="377"/>
@@ -875,7 +875,7 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="431"/>
<source>Enable CPU Debugging</source>
- <translation>Activer le Débogage CPU</translation>
+ <translation>Activer le débogage CPU</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="438"/>
@@ -894,49 +894,29 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Créer un minidump après un crash</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Activez cette option pour afficher la dernière liste de commandes audio générée sur la console. N&apos;affecte que les jeux utilisant le moteur de rendu audio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Déversez les commandes audio à la console**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Activer les services de rapport verbeux**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Ces options seront réinitialisées automatiquement lorsque yuzu fermera.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Redémarrage nécessaire</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu doit redémarrer pour appliquer ce paramètre.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Applet Web non compilé</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Création de minidump non compilé</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1355,7 +1335,7 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Séquence de touches conflictuelle</translation>
</message>
@@ -1376,27 +1356,37 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<translation>Invalide</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>Paramètres de raccourci invalides</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation>Une erreur s&apos;est produite. Veuillez signaler ce problème sur GitHub.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Restaurer les paramètres par défaut</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Effacer</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Séquence de bouton conflictuelle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>La séquence de bouton par défaut est déjà assignée à : %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>La séquence de touches par défaut est déjà attribuée à : %1</translation>
</message>
@@ -1695,7 +1685,7 @@ Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2609"/>
<source>Ring Controller</source>
- <translation>Contrôleur Anneau</translation>
+ <translation>Contrôleur anneau</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
@@ -3374,67 +3364,72 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<translation>Afficher la colonne des types de fichier</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>Afficher la colonne de temps de jeu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Taille de l&apos;icône du jeu :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Taille de l&apos;icône du dossier :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Texte rangée 1 :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Texte rangée 2 :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Captures d&apos;écran</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Demander où enregistrer les captures d&apos;écran (Windows uniquement)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Chemin du dossier des captures d&apos;écran :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>TextLabel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Résolution :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Sélectionnez le chemin du dossier des captures d&apos;écran...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Auto (%1 x %2, %3 x %4)</translation>
@@ -3752,817 +3747,821 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Des données anonymes sont collectées&lt;/a&gt; pour aider à améliorer yuzu. &lt;br/&gt;&lt;br/&gt;Voulez-vous partager vos données d&apos;utilisations avec nous ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Télémétrie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
- <translation>Installation Vulkan Cassée Détectée</translation>
+ <translation>Détection d&apos;une installation Vulkan endommagée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>L&apos;initialisation de Vulkan a échoué lors du démarrage.&lt;br&gt;&lt;br&gt;Cliquez &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;ici pour obtenir des instructions pour résoudre le problème&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Exécution d&apos;un jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
- <translation>Chargement du Web Applet...</translation>
+ <translation>Chargement de l&apos;applet web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Désactiver l&apos;applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>La désactivation de l&apos;applet Web peut entraîner un comportement indéfini et ne doit être utilisée qu&apos;avec Super Mario 3D All-Stars. Voulez-vous vraiment désactiver l&apos;applet Web ?
(Cela peut être réactivé dans les paramètres de débogage.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>La quantité de shaders en cours de construction</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Le multiplicateur de mise à l&apos;échelle de résolution actuellement sélectionné.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Valeur actuelle de la vitesse de l&apos;émulation. Des valeurs plus hautes ou plus basses que 100% indique que l&apos;émulation fonctionne plus vite ou plus lentement qu&apos;une véritable Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Combien d&apos;image par seconde le jeu est en train d&apos;afficher. Ceci vas varier de jeu en jeu et de scènes en scènes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Temps pris pour émuler une image par seconde de la switch, sans compter le limiteur d&apos;image par seconde ou la synchronisation verticale. Pour une émulation à pleine vitesse, ceci devrait être au maximum à 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Remettre le son</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Couper le son</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Réinitialiser le volume</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Effacer les fichiers récents</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>La souris émulée est activée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>La saisie réelle de la souris et le panoramique de la souris sont incompatibles. Veuillez désactiver la souris émulée dans les paramètres avancés d&apos;entrée pour permettre le panoramique de la souris.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Continuer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Avertissement : Le Format de jeu est dépassé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Vous utilisez un format de ROM déconstruite pour ce jeu, qui est donc un format dépassé qui à été remplacer par d&apos;autre. Par exemple les formats NCA, NAX, XCI, ou NSP. Les destinations de ROM déconstruites manque des icônes, des métadonnée et du support de mise à jour.&lt;br&gt;&lt;br&gt;Pour une explication des divers formats Switch que yuzu supporte, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Regardez dans le wiki&lt;/a&gt;. Ce message ne sera pas montré une autre fois.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Erreur lors du chargement de la ROM !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Le format de la ROM n&apos;est pas supporté.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Une erreur s&apos;est produite lors de l&apos;initialisation du noyau dédié à la vidéo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu a rencontré une erreur en exécutant le cœur vidéo. Cela est généralement causé par des pilotes graphiques trop anciens. Veuillez consulter les logs pour plus d&apos;informations. Pour savoir comment accéder aux logs, veuillez vous référer à la page suivante : &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Comment partager un fichier de log &lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Erreur lors du chargement de la ROM ! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Veuillez suivre &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;le guide de démarrage rapide yuzu&lt;/a&gt; pour retransférer vos fichiers.&lt;br&gt;Vous pouvez vous référer au wiki yuzu&lt;/a&gt; ou le Discord yuzu&lt;/a&gt; pour de l&apos;assistance.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Une erreur inconnue est survenue. Veuillez consulter le journal des logs pour plus de détails.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Fermeture du logiciel...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Enregistrer les données</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Donnés du Mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Erreur dans l&apos;ouverture du dossier %1.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Le dossier n&apos;existe pas !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Erreur lors de l&apos;ouverture des Shader Cache Transferable</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Impossible de créer le dossier de cache du shader pour ce jeu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Erreur en enlevant le contenu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Erreur en enlevant la Mise à Jour</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Erreur en enlevant le DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Enlever les données du jeu installé ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Enlever la mise à jour du jeu installé ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Enlever le DLC du jeu installé ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Supprimer l&apos;entrée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Supprimé avec succès</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Suppression du jeu de base installé avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Le jeu de base n&apos;est pas installé dans la NAND et ne peut pas être supprimé.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Suppression de la mise à jour installée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Il n&apos;y a pas de mise à jour installée pour ce titre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Il n&apos;y a pas de DLC installé pour ce titre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Suppression de %1 DLC installé(s) avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Supprimer la Cache OpenGL de Shader Transférable?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Supprimer la Cache Vulkan de Shader Transférable?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Supprimer Toutes les Caches de Shader Transférable?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Supprimer la configuration personnalisée du jeu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Supprimer le stockage du cache ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Supprimer fichier</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>Supprimer les données de temps de jeu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>Réinitialiser le temps de jeu ?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Erreur lors de la suppression du cache de shader transférable</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Un shader cache pour ce titre n&apos;existe pas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Suppression du cache de shader transférable avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Échec de la suppression du cache de shader transférable.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Erreur lors de la suppression du cache de pipeline de pilotes Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Échec de la suppression du cache de pipeline de pilotes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Erreur durant la Suppression des Caches de Shader Transférable</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Suppression des caches de shader transférable effectuée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Impossible de supprimer le dossier de la cache de shader transférable.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Erreur lors de la suppression de la configuration personnalisée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Il n&apos;existe pas de configuration personnalisée pour ce titre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Suppression de la configuration de jeu personnalisée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Échec de la suppression de la configuration personnalisée du jeu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>L&apos;extraction de la RomFS a échoué !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Une erreur s&apos;est produite lors de la copie des fichiers RomFS ou l&apos;utilisateur a annulé l&apos;opération.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Plein</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Squelette</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Sélectionnez le mode d&apos;extraction de la RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Veuillez sélectionner la manière dont vous souhaitez que le fichier RomFS soit extrait.&lt;br&gt;Full copiera tous les fichiers dans le nouveau répertoire, tandis que&lt;br&gt;skeleton créera uniquement la structure de répertoires.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Il n&apos;y a pas assez d&apos;espace libre dans %1 pour extraire la RomFS. Veuillez libérer de l&apos;espace ou sélectionner un autre dossier d&apos;extraction dans Émulation &gt; Configurer &gt; Système &gt; Système de fichiers &gt; Extraire la racine</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Extraction de la RomFS ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Annuler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extraction de la RomFS réussi !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>L&apos;opération s&apos;est déroulée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>La vérification de l&apos;intégrité n&apos;a pas pu être effectuée !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>La validité du contenu du fichier n&apos;a pas été vérifiée.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>La vérification de l&apos;intégrité a échoué !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>Le contenu du fichier pourrait être corrompu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>Vérification de l&apos;intégrité...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>La vérification de l&apos;intégrité a réussi !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Créer un raccourci</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Cela créera un raccourci vers l&apos;AppImage actuelle. Cela peut ne pas fonctionner correctement si vous mettez à jour. Continuer ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Impossible de créer un raccourci sur le bureau. Le chemin &quot;%1&quot; n&apos;existe pas.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Impossible de créer un raccourci dans le menu des applications. Le chemin &quot;%1&quot; n&apos;existe pas et ne peut pas être créé.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>Impossible de créer un raccourci. Le chemin &quot;%1&quot; n&apos;existe pas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Créer une icône</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Impossible de créer le fichier d&apos;icône. Le chemin &quot;%1&quot; n&apos;existe pas et ne peut pas être créé.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Démarrer %1 avec l&apos;émulateur Yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Impossible de créer un raccourci vers %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Création réussie d&apos;un raccourci vers %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Erreur lors de l&apos;ouverture %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Sélectionner un répertoire</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Propriétés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Les propriétés du jeu n&apos;ont pas pu être chargées.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Exécutable Switch (%1);;Tous les fichiers (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Charger un fichier</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Ouvrir le dossier des ROM extraites</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Destination sélectionnée invalide</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Le répertoire que vous avez sélectionné ne contient pas de fichier &quot;main&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Fichier Switch installable (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Installer les fichiers</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n fichier restant</numerusform><numerusform>%n fichiers restants</numerusform><numerusform>%n fichiers restants</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installation du fichier &quot;%1&quot; ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Résultats d&apos;installation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Pour éviter d&apos;éventuels conflits, nous déconseillons aux utilisateurs d&apos;installer des jeux de base sur la NAND.
Veuillez n&apos;utiliser cette fonctionnalité que pour installer des mises à jour et des DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n fichier a été nouvellement installé</numerusform><numerusform>%n fichiers ont été nouvellement installés</numerusform><numerusform>%n fichiers ont été nouvellement installés</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n fichier a été écrasé</numerusform><numerusform>%n fichiers ont été écrasés</numerusform><numerusform>%n fichiers ont été écrasés</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n fichier n&apos;a pas pu être installé</numerusform><numerusform>%n fichiers n&apos;ont pas pu être installés</numerusform><numerusform>%n fichiers n&apos;ont pas pu être installés</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Application Système</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Archive Système</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Mise à jour de l&apos;application système</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Paquet micrologiciel (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Paquet micrologiciel (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Mise à jour de jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC de jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Titre Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Sélectionner le type d&apos;installation du NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Veuillez sélectionner le type de titre auquel vous voulez installer ce NCA :
(Dans la plupart des cas, le titre par défaut : &apos;Jeu&apos; est correct.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Échec de l&apos;installation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Le type de titre que vous avez sélectionné pour le NCA n&apos;est pas valide.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Fichier non trouvé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Fichier &quot;%1&quot; non trouvé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Éxigences matérielles non respectées</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Votre système ne correspond pas aux éxigences matérielles. Les rapports de comptabilité ont été désactivés.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Compte yuzu manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Pour soumettre un test de compatibilité pour un jeu, vous devez lier votre compte yuzu.&lt;br&gt;&lt;br/&gt;Pour lier votre compte yuzu, aller à Emulation &amp;gt; Configuration&amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Erreur lors de l&apos;ouverture de l&apos;URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Impossible d&apos;ouvrir l&apos;URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Enregistrement TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Écraser le fichier du joueur 1 ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Configuration invalide détectée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Le contrôleur portable ne peut pas être utilisé en mode TV. La manette pro sera sélectionné.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>L&apos;amiibo actuel a été retiré</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Erreur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Le jeu actuel ne cherche pas d&apos;amiibos.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Fichier Amiibo (%1);; Tous les fichiers (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Charger un Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Erreur lors du chargement des données Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Le fichier choisi n&apos;est pas un amiibo valide</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Le fichier sélectionné est déjà utilisé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Une erreur inconnue s&apos;est produite</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4571,145 +4570,177 @@ Veuillez n&apos;utiliser cette fonctionnalité que pour installer des mises à j
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation>Pas de firmware disponible</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>Veuillez installer le firmware pour utiliser l&apos;applet de l&apos;album.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>Applet de l&apos;album</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>L&apos;applet de l&apos;album n&apos;est pas disponible. Veuillez réinstaller le firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>Veuillez installer le firmware pour utiliser l&apos;applet du cabinet.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Applet du cabinet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>L&apos;applet du cabinet n&apos;est pas disponible. Veuillez réinstaller le firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation>Veuillez installer le firmware pour utiliser l&apos;éditeur Mii.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation>Applet de l&apos;éditeur Mii</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation>L&apos;éditeur Mii n&apos;est pas disponible. Veuillez réinstaller le firmware.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Capture d&apos;écran</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Image PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>État du TAS : En cours d&apos;exécution %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>État du TAS : Enregistrement %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>État du TAS : Inactif %1:%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>État du TAS : Invalide</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Stopper l&apos;exécution</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Stopper l&apos;en&amp;registrement</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>En&amp;registrer</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Compilation: %n shader</numerusform><numerusform>Compilation : %n shaders</numerusform><numerusform>Compilation : %n shaders</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Échelle : %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Vitesse : %1% / %2% </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Vitesse : %1% </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Jeu : %1 IPS (Débloqué)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Jeu : %1 FPS </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Frame : %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>AUCUN AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUME : MUET</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>VOLUME : %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmer la réinstallation de la clé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4726,37 +4757,37 @@ et éventuellement faites des sauvegardes.
Cela supprimera vos fichiers de clé générés automatiquement et ré exécutera le module d&apos;installation de clé.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Fusibles manquants</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- BOOT0 manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- BCPKG2-1-Normal-Main manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Composants de dérivation manquants</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Les clés de chiffrement sont manquantes. &lt;br&gt;Veuillez suivre &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;le guide de démarrage rapide yuzu&lt;/a&gt; pour obtenir tous vos clés, firmware et jeux.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4765,49 +4796,49 @@ Cela peut prendre jusqu&apos;à une minute en fonction
des performances de votre système.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Installation des clés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Échec du déchiffrement de l&apos;archive système.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Les clés de chiffrement n&apos;ont pas réussi à déchiffrer le firmware. &lt;br&gt;Veuillez suivre &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;le guide de démarrage rapide du yuzu&lt;/a&gt; pour obtenir toutes vos clés, firmware et jeux.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Sélectionner la cible d&apos;extraction du RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Veuillez sélectionner quel RomFS vous voulez extraire.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Êtes vous sûr de vouloir fermer yuzu ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Êtes-vous sûr d&apos;arrêter l&apos;émulation ? Tout progrès non enregistré sera perdu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4959,241 +4990,251 @@ Voulez-vous ignorer ceci and quitter quand même ?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Préférer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Démarrer le jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Démarrer le jeu sans configuration personnalisée</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Ouvrir l&apos;emplacement des données de sauvegarde</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Ouvrir l&apos;emplacement des données des mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
- <translation>Ouvrir la Cache de Pipeline Transférable</translation>
+ <translation>Ouvrir le cache de pipelines transférable</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Supprimer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Supprimer mise à jour installée</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Supprimer tous les DLC installés</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Supprimer la configuration personnalisée</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>Supprimer les données de temps de jeu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Supprimer le stockage du cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
- <translation>Supprimer la Cache de Pipeline OpenGL</translation>
+ <translation>Supprimer le cache de pipelines OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
- <translation>Supprimer la Cache de Pipeline Vulkan</translation>
+ <translation>Supprimer le cache de pipelines Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
- <translation>Supprimer Toutes les Caches de Pipeline</translation>
+ <translation>Supprimer tous les caches de pipelines</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Supprimer tout le contenu installé</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Extraire la RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Décharger RomFS vers SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Vérifier l&apos;intégrité</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Copier l&apos;ID du titre dans le Presse-papiers</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Accédez à l&apos;entrée GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Créer un raccourci</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Ajouter au bureau</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Ajouter au menu des applications</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Propriétés</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Scanner les sous-dossiers</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Supprimer le répertoire du jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Monter</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Descendre</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Ouvrir l&apos;emplacement du répertoire</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Effacer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nom</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Compatibilité</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Extensions</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Type de fichier</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Taille</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>Temps de jeu</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>En jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Le jeu se lance, mais crash ou des bugs majeurs l&apos;empêchent d&apos;être complété.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Parfait</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Le jeu peut être joué sans problèmes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Jouable</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Le jeu fonctionne avec des glitchs graphiques ou audio mineurs et est jouable du début à la fin.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Le jeu charge, mais ne peut pas progresser après le menu de démarrage.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Ne démarre pas</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Le jeu crash au lancement.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Non testé</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Le jeu n&apos;a pas encore été testé.</translation>
</message>
@@ -5201,7 +5242,7 @@ Voulez-vous ignorer ceci and quitter quand même ?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Double-cliquez pour ajouter un nouveau dossier à la liste de jeux</translation>
</message>
@@ -5214,12 +5255,12 @@ Voulez-vous ignorer ceci and quitter quand même ?</translation>
<translation><numerusform>%1 sur %n résultat</numerusform><numerusform>%1 sur %n résultats</numerusform><numerusform>%1 sur %n résultats</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filtre :</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Entrez un motif à filtrer</translation>
</message>
@@ -5337,6 +5378,7 @@ Message de débogage : </translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Fenêtre Principale</translation>
</message>
@@ -5442,6 +5484,11 @@ Message de débogage : </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation>Activer la capture renderdoc</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Activer la barre d&apos;état</translation>
</message>
@@ -5680,186 +5727,216 @@ Message de débogage : </translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Aide</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Installer des fichiers sur la NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>&amp;Charger un fichier...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>&amp;Charger un dossier</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>Q&amp;uitter</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Arrêter</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Réinitialiser les clés...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation>&amp;Vérifier les contenus installés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;À propos de yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>&amp;Mode fenêtre unique</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>&amp;Configurer...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>&amp;Afficher les en-têtes du widget Dock</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>&amp;Afficher la barre de filtre</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>&amp;Afficher la barre d&apos;état</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Afficher la barre d&apos;état</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Parcourir le menu des jeux publics</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Créer un salon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Quitter le salon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Connexion directe au salon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Afficher le salon actuel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>P&amp;lein écran</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Redémarrer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Charger/Retirer &amp;Amiibo…</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Signaler la compatibilité</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Ouvrir la &amp;page des mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
- <translation>Ouvrir le &amp;guide de Démarrage rapide</translation>
+ <translation>Ouvrir le &amp;guide de démarrage rapide</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Ouvrir le &amp;dossier de Yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Capture d&apos;écran</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>Ouvrir l&apos;&amp;album</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>&amp;Définir le surnom et le propriétaire</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>&amp;Supprimer les données du jeu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>&amp;Restaurer l&apos;amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>&amp;Formater l&apos;amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation>Ouvrir l&apos;&amp;éditeur Mii</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Configurer TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Configurer le j&amp;eu actuel...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Démarrer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Réinitialiser</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>En&amp;registrer</translation>
</message>
@@ -6167,27 +6244,27 @@ p, li { white-space: pre-wrap; }
<translation>Ne joue pas à un jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Titres installés sur la SD</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Titres installés sur la NAND</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Titres Système</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Ajouter un nouveau répertoire de jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoris</translation>
</message>
@@ -6713,7 +6790,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Manette Switch Pro</translation>
</message>
@@ -6726,7 +6803,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Deux Joycons</translation>
</message>
@@ -6739,7 +6816,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon gauche</translation>
</message>
@@ -6752,7 +6829,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon droit</translation>
</message>
@@ -6781,7 +6858,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Mode Portable</translation>
</message>
@@ -6897,32 +6974,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>Pas assez de manettes.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Manette GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poké Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Manette NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Manette SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Manette N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/hu.ts b/dist/languages/hu.ts
index 3c14971ba..863e7383b 100644
--- a/dist/languages/hu.ts
+++ b/dist/languages/hu.ts
@@ -29,7 +29,7 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Ubuntu&apos;; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;A yuzu egy kísérleti nyílt forráskódú emulátor a Nintendo Switchhez, GPLv3.0+ licenccel.&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;A yuzu egy kísérleti, nyílt forráskódú Nintendo Switch emulátor, amely a GPLv3.0+ licenc alatt áll.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:&apos;MS Shell Dlg 2&apos;; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;Ezt a szoftvert ne használd, ha nem legálisan szerezted meg a játékaidat.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -213,7 +213,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
<source>%1 - %2 (%3/%4 members) - connected</source>
- <translation>%1 - %2 (%3/%4 tagok) - csatlakoztatva</translation>
+ <translation>%1 - %2 (%3/%4 tag) - csatlakoztatva</translation>
</message>
</context>
<context>
@@ -237,7 +237,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="36"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Should you choose to submit a test case to the &lt;/span&gt;&lt;a href=&quot;https://yuzu-emu.org/game/&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;yuzu Compatibility List&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;, The following information will be collected and displayed on the site:&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Hardware Information (CPU / GPU / Operating System)&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Which version of yuzu you are running&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The connected yuzu account&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Szeretnél küldeni egy tesztelési jelentést a &lt;/span&gt;&lt;a href=&quot;https://yuzu-emu.org/game/&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;yuzu Kompatibilitás Listájára&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;, A következő információkat fogjuk begyűjteni és megjeleníteni az oldalon:&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Hardver Információk (CPU / GPU / Operációs rendszer)&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A yuzu, milyen verzión fut&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A használt yuzu fiók&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Ha úgy döntesz, hogy tesztesetet küldesz a &lt;/span&gt;&lt;a href=&quot;https://yuzu-emu.org/game/&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;yuzu kompatibilitási listára&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;,a következő információkat gyűjtjük és jelenítjük meg az oldalon:&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Hardverinformáció (CPU / GPU / operációs rendszer)&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A yuzu futtatott verziója&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A csatlakoztatott yuzu-fiók&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="77"/>
@@ -373,13 +373,13 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Automatikus (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Alapértelmezett (%1)</translation>
@@ -404,12 +404,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
<source>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</source>
- <translation type="unfinished"/>
+ <translation>Válaszd ki, honnan származik az emulált kamera képe. Ez lehet egy virtuális vagy egy valódi kamera.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="52"/>
<source>Camera Image Source:</source>
- <translation type="unfinished"/>
+ <translation>Kamerakép forrása:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
@@ -434,7 +434,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
<source>Restore Defaults</source>
- <translation>Visszaállítás alapértelmezettre</translation>
+ <translation>Visszaállítás</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.cpp" line="140"/>
@@ -447,7 +447,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="17"/>
@@ -480,7 +480,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="17"/>
@@ -521,7 +521,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="60"/>
<source>Enable block linking</source>
- <translation type="unfinished"/>
+ <translation>Blokk összekapcsolás engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="67"/>
@@ -533,7 +533,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="72"/>
<source>Enable return stack buffer</source>
- <translation type="unfinished"/>
+ <translation>Visszatérési puffer engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="79"/>
@@ -552,36 +552,42 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<source>
&lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
</source>
- <translation type="unfinished"/>
+ <translation>
+ &lt;div&gt;Engedélyezi az IR-optimalizálást, amely csökkenti a CPU-kontextus struktúrájához való szükségtelen hozzáféréseket.&lt;/div&gt;
+ </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="96"/>
<source>Enable context elimination</source>
- <translation type="unfinished"/>
+ <translation>Kontextus kiküszöbölésének engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="103"/>
<source>
&lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
</source>
- <translation type="unfinished"/>
+ <translation>
+ &lt;div&gt;Lehetővé teszi az olyan IR-optimalizációkat, amelyek állandó továbbítással járnak.&lt;/div&gt;
+ </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="108"/>
<source>Enable constant propagation</source>
- <translation type="unfinished"/>
+ <translation>Állandó továbbítás engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="115"/>
<source>
&lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
</source>
- <translation type="unfinished"/>
+ <translation>
+ &lt;div&gt;Engedélyezi az egyéb IR-optimalizációkat. &lt;/div&gt;
+ </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="120"/>
<source>Enable miscellaneous optimizations</source>
- <translation type="unfinished"/>
+ <translation>Egyéb optimalizációk engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="127"/>
@@ -666,7 +672,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="85"/>
<source>Enable GDB Stub</source>
- <translation type="unfinished"/>
+ <translation>GDB Stub engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="119"/>
@@ -681,22 +687,22 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="163"/>
<source>Open Log Location</source>
- <translation>Naplózási Hely Megnyitása</translation>
+ <translation>Naplózási hely megnyitása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
<source>Global Log Filter</source>
- <translation>Globális Naplózási Szűrő</translation>
+ <translation>Globális naplózási szűrő</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="213"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
- <translation>Ha bepipálva marad, a naplózásnak a maximális nagysága 100 MB-ról 1 GB-ra növekszik</translation>
+ <translation>Ha be van jelölve, a napló maximális mérete 100 MB-ról 1 GB-ra nő.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="216"/>
<source>Enable Extended Logging**</source>
- <translation>Bővített Naplózás Engedélyezése</translation>
+ <translation>Bővített naplózás engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="223"/>
@@ -721,7 +727,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
<source>When checked, it executes shaders without loop logic changes</source>
- <translation>Ha be van pipálva, végrehajtja az árnyékolókat ismétlő logikai változtatások nélkül</translation>
+ <translation>Ha be van jelölve, végrehajtja az árnyékolókat ismétlő logikai változtatások nélkül</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="269"/>
@@ -731,7 +737,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="279"/>
<source>When checked, it disables the macro HLE functions. Enabling this makes games run slower</source>
- <translation>Ha bepipálva marad, letiltja a macro HLE funkciókat. Ha engedélyezi, lassabban futnak a játékok</translation>
+ <translation>Ha be van jelölve, letiltja a macro HLE funkciókat. Ennek engedélyezése lelassítja a játékok sebességét.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="282"/>
@@ -741,37 +747,37 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="292"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
- <translation type="unfinished"/>
+ <translation>Ha be van jelölve, ki fogja menteni a GPU összes makróprogramját.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="295"/>
<source>Dump Maxwell Macros</source>
- <translation type="unfinished"/>
+ <translation>Maxwell makrók kimentése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="302"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
- <translation type="unfinished"/>
+ <translation>Ha be van jelölve, engedélyezi az Nsight Aftermath összeomlási naplókat.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable Nsight Aftermath</source>
- <translation>Nsight Aftermath Engedélyezése</translation>
+ <translation>Nsight Aftermath engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
- <translation type="unfinished"/>
+ <translation>Ha be van jelölve, a yuzu naplózza a fordított pipeline gyorsítótár statisztikáit.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="315"/>
<source>Enable Shader Feedback</source>
- <translation>Árnyékoló Visszajelzés Engedélyezése</translation>
+ <translation>Árnyékoló visszajelzés engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="325"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
- <translation>Ha bepipálva marad, letiltja a macro Just In Time összegyűjtőt. Ha engedélyezi, lassabban futnak a játékok</translation>
+ <translation>Ha be van jelölve, letiltja a macro Just In Time fordítót. Ennek engedélyezése lelassítja a játékok sebességét.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="328"/>
@@ -781,27 +787,27 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="354"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
- <translation>Ha bepipálva marad, a grafikai API lassabb hibakereső módba fog lépni</translation>
+ <translation>Ha be van jelölve, a grafikus API lassabb hibakereső módba lép.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="357"/>
<source>Enable Graphics Debugging</source>
- <translation>Grafikai Hibakereső Engedélyezése</translation>
+ <translation>Grafikai hibakereső engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="367"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
- <translation type="unfinished"/>
+ <translation>Ha be van jelölve, az összes eredeti assembler árnyékolót ki fogja menteni a lemez árnyékoló gyorsítótárból vagy a játékból, ahogyan azt találja.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="370"/>
<source>Dump Game Shaders</source>
- <translation type="unfinished"/>
+ <translation>Játék árnyékolók kimentése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="377"/>
<source>Enable Renderdoc Hotkey</source>
- <translation type="unfinished"/>
+ <translation>Renderdoc gyorsgomb engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="387"/>
@@ -811,22 +817,22 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="393"/>
<source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
- <translation>Engedélyezi a yuzunak, hogy keressen működő Vulkan környezetet, amikor a program elindul. Tiltsa le, ha okoz problémát yuzu észlelésénél külsős programoknál</translation>
+ <translation>Lehetővé teszi, hogy a yuzu ellenőrizze a Vulkan környezet működését a program indításakor. Ha ez problémát okoz a külső programoknak a yuzu észlelésében, akkor tiltsd le ezt az opciót.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="396"/>
<source>Perform Startup Vulkan Check</source>
- <translation>Elindítási Vulkan Ellenőrzés Végrehajtása</translation>
+ <translation>Vulkan ellenőrzése indításkor</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="403"/>
<source>Disable Web Applet</source>
- <translation>Webalkalmazás letiltása</translation>
+ <translation>Web applet letiltása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="410"/>
<source>Enable All Controller Types</source>
- <translation>Összes Kontroller Típus Engedélyezése</translation>
+ <translation>Összes vezérlőtípus engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="417"/>
@@ -836,12 +842,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="424"/>
<source>Kiosk (Quest) Mode</source>
- <translation>Kiosk (Quest) Mód</translation>
+ <translation>Kiosk (Quest) mód</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="431"/>
<source>Enable CPU Debugging</source>
- <translation>CPU Hibakereső Engedélyezése</translation>
+ <translation>CPU hibakereső engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="438"/>
@@ -860,56 +866,36 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Ez automatikusan visszaáll, amikor a yuzu leáll.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Újraindítás Szükséges</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>Szükséges a yuzu újraindítása, hogy alkalmazzuk ezt a beállítást.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation type="unfinished"/>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation type="unfinished"/>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
<message>
<location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="14"/>
<source>Configure Debug Controller</source>
- <translation>Hibakeresési Kontroller Konfigurálása</translation>
+ <translation>Hibakeresési vezérlő konfigurálása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="40"/>
@@ -919,7 +905,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="47"/>
<source>Defaults</source>
- <translation>Alapértelmezettek</translation>
+ <translation>Alap</translation>
</message>
</context>
<context>
@@ -927,7 +913,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_debug_tab.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug_tab.ui" line="17"/>
@@ -951,7 +937,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure.ui" line="67"/>
<source>Some settings are only available when a game is not running.</source>
- <translation>Valamely beállítások csak akkor elérhetőek, amikor nem fut játék.</translation>
+ <translation>Néhány beállítás csak akkor érhető el, amikor nem fut játék.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="62"/>
@@ -1035,7 +1021,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="17"/>
@@ -1099,7 +1085,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="159"/>
<source>Dump ExeFS</source>
- <translation type="unfinished"/>
+ <translation>ExeFS kimentése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="168"/>
@@ -1109,7 +1095,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="175"/>
<source>Dump Root</source>
- <translation type="unfinished"/>
+ <translation>Gyökér kimentése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="201"/>
@@ -1132,27 +1118,27 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="93"/>
<source>Select Emulated NAND Directory...</source>
- <translation>Válasszon ki Emulált NAND Könyvtárat...</translation>
+ <translation>Emulált NAND könyvtár kiválasztása...</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="96"/>
<source>Select Emulated SD Directory...</source>
- <translation>Válasszon ki Emulált SD Könyvtárat...</translation>
+ <translation>Emulált SD könyvtár kiválasztása...</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="99"/>
<source>Select Gamecard Path...</source>
- <translation>Válasszon ki Játékkártya Könyvtárat...</translation>
+ <translation>Játékkártya könyvtár kiválasztása...</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="102"/>
<source>Select Dump Directory...</source>
- <translation type="unfinished"/>
+ <translation>Kimentési mappa kiválasztása...</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="105"/>
<source>Select Mod Load Directory...</source>
- <translation>Válasszon ki Mod Betöltő Könyvtárat...</translation>
+ <translation>Mod betöltő könyvtár kiválasztása...</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="132"/>
@@ -1175,7 +1161,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="17"/>
@@ -1186,7 +1172,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="82"/>
<source>Reset All Settings</source>
- <translation>Összes Beállítás Visszaállítása</translation>
+ <translation>Összes beállítás visszaállítása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_general.cpp" line="70"/>
@@ -1204,7 +1190,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="17"/>
@@ -1214,12 +1200,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="25"/>
<source>API Settings</source>
- <translation>API Beállítások</translation>
+ <translation>API beállítások</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="58"/>
<source>Graphics Settings</source>
- <translation>Grafikai Beállítások</translation>
+ <translation>Grafikai beállítások</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="103"/>
@@ -1263,7 +1249,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="17"/>
@@ -1273,7 +1259,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="25"/>
<source>Advanced Graphics Settings</source>
- <translation>Haladó Grafikai Beállítások</translation>
+ <translation>Haladó grafikai beállítások</translation>
</message>
</context>
<context>
@@ -1281,7 +1267,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="14"/>
<source>Hotkey Settings</source>
- <translation>Gyorsgomb Beállítások</translation>
+ <translation>Gyorsgomb beállítások</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="17"/>
@@ -1296,12 +1282,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="45"/>
<source>Clear All</source>
- <translation>Összes Törlése</translation>
+ <translation>Összes törlése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="52"/>
<source>Restore Defaults</source>
- <translation>Visszaállítás alapértelmezettre</translation>
+ <translation>Visszaállítás</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="100"/>
@@ -1316,12 +1302,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="100"/>
<source>Controller Hotkey</source>
- <translation>Kontroller Gyorsgomb</translation>
+ <translation>Vezérlő gyorsgomb</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Ütköző kulcssorozat</translation>
</message>
@@ -1342,27 +1328,37 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<translation>Érvénytelen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>Érvénytelen gyorsbillentyű beállítások</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
- <translation>Alapértelmezettre állítás</translation>
+ <translation>Alapértelmezés</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Törlés</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Ütköző gombsor</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Az alapértelmezett gombsor már hozzá van rendelve a: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Az alapértelmezett kulcssorozat már hozzá van rendelve a: %1</translation>
</message>
@@ -1372,7 +1368,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="14"/>
<source>ConfigureInput</source>
- <translation>Bevitel Konfigurálása</translation>
+ <translation>Bevitel konfigurálása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="39"/>
@@ -1431,12 +1427,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="138"/>
<source>Console Mode</source>
- <translation>Konzol Mód</translation>
+ <translation>Konzol mód</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="159"/>
<source>Docked</source>
- <translation>Dokkolva</translation>
+ <translation>Dokkolt</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="169"/>
@@ -1462,7 +1458,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="296"/>
<source>Controllers</source>
- <translation>Kontrollerek</translation>
+ <translation>Vezérlők</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="324"/>
@@ -1512,7 +1508,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="494"/>
<source>Defaults</source>
- <translation>Alapértelmezettek</translation>
+ <translation>Alap</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input.ui" line="537"/>
@@ -1525,12 +1521,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="14"/>
<source>Configure Input</source>
- <translation>Bevitel Konfigurálása</translation>
+ <translation>Bevitel konfigurálása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="74"/>
<source>Joycon Colors</source>
- <translation>Joycon Színei</translation>
+ <translation>Joycon színei</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="125"/>
@@ -1547,7 +1543,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1955"/>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2241"/>
<source>L Body</source>
- <translation>Bal Test</translation>
+ <translation>Bal test</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="219"/>
@@ -1559,7 +1555,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2010"/>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2296"/>
<source>L Button</source>
- <translation>Bal Gomb</translation>
+ <translation>Bal gomb</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="295"/>
@@ -1571,7 +1567,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2086"/>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2372"/>
<source>R Body</source>
- <translation>Jobb Test</translation>
+ <translation>Jobb test</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="350"/>
@@ -1583,7 +1579,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2141"/>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2427"/>
<source>R Button</source>
- <translation>Jobb Gomb</translation>
+ <translation>Jobb gomb</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="411"/>
@@ -1623,7 +1619,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2533"/>
<source>Emulated Devices</source>
- <translation>Emulált Eszközök</translation>
+ <translation>Emulált eszközök</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2545"/>
@@ -1648,7 +1644,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2595"/>
<source>Debug Controller</source>
- <translation>Kontroller Hibakeresése</translation>
+ <translation>Vézérlő hibakeresése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2602"/>
@@ -1661,12 +1657,12 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2609"/>
<source>Ring Controller</source>
- <translation>Ring Kontroller</translation>
+ <translation>Ring kontroller</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
<source>Infrared Camera</source>
- <translation>Infravörös Kamera</translation>
+ <translation>Infravörös kamera</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2640"/>
@@ -1676,7 +1672,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2652"/>
<source>Emulate Analog with Keyboard Input</source>
- <translation>Analóg Emulálása Billentyűzet Bevitellel</translation>
+ <translation>Analóg emulálása billentyűzet bevitellel</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2659"/>
@@ -1688,17 +1684,17 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2668"/>
<source>Enable XInput 8 player support (disables web applet)</source>
- <translation type="unfinished"/>
+ <translation>XInput 8 játékos támogatás engedélyezése (web appletet letiltja)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2681"/>
<source>Enable UDP controllers (not needed for motion)</source>
- <translation type="unfinished"/>
+ <translation>UDP vezérlők engedélyezése (motionhöz nem szükséges)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2694"/>
<source>Controller navigation</source>
- <translation>Kontroller nagiváció</translation>
+ <translation>Kontroller navigáció</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2710"/>
@@ -1713,7 +1709,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2733"/>
<source>Allows unlimited uses of the same Amiibo in games that would otherwise limit you to one use.</source>
- <translation>Engedélyezi az ugyanolyan Amiibo korlátlan használatát, olyan játékokban ahol másképpen egyszeri használatra lenne limitálva.</translation>
+ <translation>Lehetővé teszi, hogy ugyanazt az Amiibo-t korlátlanul használd olyan játékokban, amelyek egyébként csak egyszerre engednék használni.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2742"/>
@@ -1731,7 +1727,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="17"/>
@@ -1741,52 +1737,52 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="28"/>
<source>Input Profiles</source>
- <translation>Beviteli Profilok</translation>
+ <translation>Beviteli profilok</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="49"/>
<source>Player 1 Profile</source>
- <translation>Játékos 1 Profilja</translation>
+ <translation>Játékos 1 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="84"/>
<source>Player 2 Profile</source>
- <translation>Játékos 2 Profilja</translation>
+ <translation>Játékos 2 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="119"/>
<source>Player 3 Profile</source>
- <translation>Játékos 3 Profilja</translation>
+ <translation>Játékos 3 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="154"/>
<source>Player 4 Profile</source>
- <translation>Játékos 4 Profilja</translation>
+ <translation>Játékos 4 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="189"/>
<source>Player 5 Profile</source>
- <translation>Játékos 5 Profilja</translation>
+ <translation>Játékos 5 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="224"/>
<source>Player 6 Profile</source>
- <translation>Játékos 6 Profilja</translation>
+ <translation>Játékos 6 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="259"/>
<source>Player 7 Profile</source>
- <translation>Játékos 7 Profilja</translation>
+ <translation>Játékos 7 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.ui" line="294"/>
<source>Player 8 Profile</source>
- <translation>Játékos 8 Profilja</translation>
+ <translation>Játékos 8 profilja</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.cpp" line="35"/>
<source>Use global input configuration</source>
- <translation type="unfinished"/>
+ <translation>Globális bemenet konfiguráció használata</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_per_game.cpp" line="47"/>
@@ -1799,7 +1795,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="14"/>
<source>Configure Input</source>
- <translation>Bevitel Konfigurálása</translation>
+ <translation>Bevitel konfigurálása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="63"/>
@@ -1809,7 +1805,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="100"/>
<source>Input Device</source>
- <translation>Bemeneti Eszköz</translation>
+ <translation>Bemeneti eszköz</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="137"/>
@@ -1929,7 +1925,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1271"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1345"/>
<source>L</source>
- <translation type="unfinished"/>
+ <translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1287"/>
@@ -1942,7 +1938,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1407"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1446"/>
<source>Minus</source>
- <translation type="unfinished"/>
+ <translation>Mínusz</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1456"/>
@@ -1955,7 +1951,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1565"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1336"/>
<source>Plus</source>
- <translation type="unfinished"/>
+ <translation>Plusz</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1575"/>
@@ -1969,7 +1965,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1339"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1346"/>
<source>R</source>
- <translation type="unfinished"/>
+ <translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1734"/>
@@ -2021,13 +2017,13 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2328"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2367"/>
<source>A</source>
- <translation type="unfinished"/>
+ <translation>A</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2410"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2449"/>
<source>B</source>
- <translation type="unfinished"/>
+ <translation>B</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2497"/>
@@ -2038,7 +2034,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3085"/>
<source>Mouse panning</source>
- <translation type="unfinished"/>
+ <translation>Egérpásztázás</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3109"/>
@@ -2060,7 +2056,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="590"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
<source>[not set]</source>
- <translation>[nincs beállítva]</translation>
+ <translation>[nincs beáll.]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
@@ -2078,7 +2074,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="401"/>
<source>Turbo button</source>
- <translation type="unfinished"/>
+ <translation>Turbó gomb</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="409"/>
@@ -2091,7 +2087,7 @@ Ez kitiltaná a fórum felhasználóneve és az IP címe alapján.</translation>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="425"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
<source>Set threshold</source>
- <translation type="unfinished"/>
+ <translation>Küszöbérték beállítása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="425"/>
@@ -2129,7 +2125,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="592"/>
<source>Center axis</source>
- <translation type="unfinished"/>
+ <translation>Középtengely</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="700"/>
@@ -2167,7 +2163,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1111"/>
<source>Handheld</source>
- <translation>Kézben</translation>
+ <translation>Kézi</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1115"/>
@@ -2177,7 +2173,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1124"/>
<source>Poke Ball Plus</source>
- <translation type="unfinished"/>
+ <translation>Poke Ball Plus</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1128"/>
@@ -2197,7 +2193,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1140"/>
<source>Sega Genesis</source>
- <translation type="unfinished"/>
+ <translation>Sega Genesis</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1344"/>
@@ -2207,7 +2203,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1347"/>
<source>Z</source>
- <translation type="unfinished"/>
+ <translation>Z</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1348"/>
@@ -2222,12 +2218,12 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1450"/>
<source>Shake!</source>
- <translation type="unfinished"/>
+ <translation>Rázd!</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1452"/>
<source>[waiting]</source>
- <translation>[várokazás]</translation>
+ <translation>[várakozás]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1547"/>
@@ -2237,7 +2233,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1547"/>
<source>Enter a profile name:</source>
- <translation type="unfinished"/>
+ <translation>Add meg a profil nevét:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1555"/>
@@ -2253,7 +2249,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1564"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>A &quot;%1&quot; beviteli profilt nem sikerült létrehozni</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1584"/>
@@ -2263,7 +2259,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1585"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>A &quot;%1&quot; beviteli profilt nem sikerült eltávolítani</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1607"/>
@@ -2273,7 +2269,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1608"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>A &quot;%1&quot; beviteli profilt nem sikerült betölteni</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1633"/>
@@ -2283,7 +2279,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1634"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
- <translation type="unfinished"/>
+ <translation>A &quot;%1&quot; beviteli profilt nem sikerült elmenteni</translation>
</message>
</context>
<context>
@@ -2301,7 +2297,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_input_profile_dialog.ui" line="47"/>
<source>Defaults</source>
- <translation>Alapértelmezettek</translation>
+ <translation>Alap</translation>
</message>
</context>
<context>
@@ -2341,7 +2337,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="85"/>
<source>CemuhookUDP Config</source>
- <translation type="unfinished"/>
+ <translation>CemuhookUDP konfig</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="91"/>
@@ -2422,7 +2418,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="193"/>
<source>Unable to add more than 8 servers</source>
- <translation type="unfinished"/>
+ <translation>8-nál több kiszolgálót nem lehet hozzáadni</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="209"/>
@@ -2442,7 +2438,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="257"/>
<source>Successfully received data from the server.</source>
- <translation type="unfinished"/>
+ <translation>Az adatok sikeresen beérkeztek a kiszolgálótól.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="259"/>
@@ -2457,7 +2453,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="288"/>
<source>UDP Test or calibration configuration is in progress.&lt;br&gt;Please wait for them to finish.</source>
- <translation type="unfinished"/>
+ <translation>UDP tesztelés vagy a kalibrálás konfigurálása folyamatban van.&lt;br&gt;Kérjük, várj, amíg befejeződik.</translation>
</message>
</context>
<context>
@@ -2465,17 +2461,17 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="6"/>
<source>Configure mouse panning</source>
- <translation type="unfinished"/>
+ <translation>Egérpásztázás konfigurálása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="12"/>
<source>Enable mouse panning</source>
- <translation type="unfinished"/>
+ <translation>Egérpásztázás engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="15"/>
<source>Can be toggled via a hotkey. Default hotkey is Ctrl + F9</source>
- <translation type="unfinished"/>
+ <translation>Gyorsgombbal kapcsolható. Alapértelmezett gyorsbillentyű: Ctrl + F9</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="24"/>
@@ -2524,7 +2520,7 @@ A tengely megfordításához mozgasd a kart először függőlegesen, majd vízs
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="129"/>
<source>Strength</source>
- <translation type="unfinished"/>
+ <translation>Erősség</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="155"/>
@@ -2545,7 +2541,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.cpp" line="50"/>
<source>Emulated mouse is enabled. This is incompatible with mouse panning.</source>
- <translation type="unfinished"/>
+ <translation>Az emulált egér engedélyezve van. Ez nem kompatibilis az egérpásztázással.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.cpp" line="83"/>
@@ -2563,7 +2559,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_network.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_network.ui" line="17"/>
@@ -2578,7 +2574,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_network.ui" line="34"/>
<source>Network Interface</source>
- <translation type="unfinished"/>
+ <translation>Hálózati adapter</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_network.cpp" line="15"/>
@@ -2591,12 +2587,12 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="20"/>
<source>Dialog</source>
- <translation type="unfinished"/>
+ <translation>Párbeszéd</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="34"/>
<source>Info</source>
- <translation type="unfinished"/>
+ <translation>Infó</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="93"/>
@@ -2636,7 +2632,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.ui" line="240"/>
<source>Some settings are only available when a game is not running.</source>
- <translation>Valamely beállítások csak akkor elérhetőek, amikor nem fut játék.</translation>
+ <translation>Néhány beállítás csak akkor érhető el, amikor nem fut játék.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="68"/>
@@ -2671,7 +2667,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="74"/>
<source>Input Profiles</source>
- <translation>Beviteli Profilok</translation>
+ <translation>Beviteli profilok</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="77"/>
@@ -2684,7 +2680,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game_addons.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game_addons.ui" line="17"/>
@@ -2694,7 +2690,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game_addons.cpp" line="46"/>
<source>Patch Name</source>
- <translation>Patch Név</translation>
+ <translation>Patch név</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_per_game_addons.cpp" line="47"/>
@@ -2707,7 +2703,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="17"/>
@@ -2780,12 +2776,12 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="221"/>
<source>Enter a new username:</source>
- <translation type="unfinished"/>
+ <translation>Add meg az új felhasználóneved:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="271"/>
<source>Select User Image</source>
- <translation type="unfinished"/>
+ <translation>Felhasználói kép kiválasztása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="272"/>
@@ -2800,7 +2796,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="282"/>
<source>Error occurred attempting to overwrite previous image at: %1.</source>
- <translation type="unfinished"/>
+ <translation>Hiba történt az előző kép felülírása során: %1.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="290"/>
@@ -2810,37 +2806,37 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="291"/>
<source>Unable to delete existing file: %1.</source>
- <translation type="unfinished"/>
+ <translation>A meglévő fájl törlése nem lehetséges: %1.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="298"/>
<source>Error creating user image directory</source>
- <translation type="unfinished"/>
+ <translation>Hiba történt a felhasználó kép könyvtárának létrehozásakor</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="299"/>
<source>Unable to create directory %1 for storing user images.</source>
- <translation type="unfinished"/>
+ <translation>Nem sikerült létrehozni a(z) %1 könyvtárat a felhasználó képeinek tárolásához.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="304"/>
<source>Error copying user image</source>
- <translation type="unfinished"/>
+ <translation>Hiba történt a felhasználói kép másolásakor</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="305"/>
<source>Unable to copy image from %1 to %2</source>
- <translation type="unfinished"/>
+ <translation>Nem sikerült kimásolni a képet innen %1 ide %2</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="314"/>
<source>Error resizing user image</source>
- <translation type="unfinished"/>
+ <translation>Hiba történt a felhasználói kép átméretezésekor</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="315"/>
<source>Unable to resize image</source>
- <translation type="unfinished"/>
+ <translation>A kép nem méretezhető át</translation>
</message>
</context>
<context>
@@ -2848,7 +2844,7 @@ Current values are %1% and %2% respectively.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="332"/>
<source>Delete this user? All of the user&apos;s save data will be deleted.</source>
- <translation type="unfinished"/>
+ <translation>Törlöd a felhasználót? Minden felhasználói adat törölve lesz.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="344"/>
@@ -2859,7 +2855,8 @@ Current values are %1% and %2% respectively.</source>
<location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="360"/>
<source>Name: %1
UUID: %2</source>
- <translation type="unfinished"/>
+ <translation>Név: %1
+UUID: %2</translation>
</message>
</context>
<context>
@@ -2926,7 +2923,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="344"/>
<source>Restore Defaults</source>
- <translation>Visszaállítás alapértelmezettre</translation>
+ <translation>Visszaállítás</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="168"/>
@@ -2936,7 +2933,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="170"/>
<source>[not set]</source>
- <translation>[nincs beállítva]</translation>
+ <translation>[nincs beáll.]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="172"/>
@@ -2977,7 +2974,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="309"/>
<source>The current mapped device is not connected</source>
- <translation type="unfinished"/>
+ <translation>Az jelenleg hozzárendelt eszköz nincs csatlakoztatva</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="313"/>
@@ -2987,7 +2984,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="336"/>
<source>[waiting]</source>
- <translation>[várokazás]</translation>
+ <translation>[várakozás]</translation>
</message>
</context>
<context>
@@ -2995,7 +2992,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_system.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_system.ui" line="17"/>
@@ -3019,7 +3016,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="11"/>
<source>TAS</source>
- <translation type="unfinished"/>
+ <translation>TAS</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="17"/>
@@ -3044,7 +3041,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
- <translation type="unfinished"/>
+ <translation>TAS funkciók engedélyezése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
@@ -3054,7 +3051,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
- <translation type="unfinished"/>
+ <translation>Végrehajtás szüneteltetése terhelés közben</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
@@ -3077,7 +3074,7 @@ UUID: %2</source>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.cpp" line="19"/>
<source>TAS Configuration</source>
- <translation type="unfinished"/>
+ <translation>TAS konfigurálása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_tas.cpp" line="49"/>
@@ -3181,7 +3178,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="14"/>
<source>Configure Touchscreen</source>
- <translation type="unfinished"/>
+ <translation>Érintőképernyő konfigurálása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="26"/>
@@ -3191,27 +3188,27 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="52"/>
<source>Touch Parameters</source>
- <translation type="unfinished"/>
+ <translation>Érintési paraméterek</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="71"/>
<source>Touch Diameter Y</source>
- <translation type="unfinished"/>
+ <translation>Érintési átmérő Y</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="91"/>
<source>Touch Diameter X</source>
- <translation type="unfinished"/>
+ <translation>Érintési átmérő X</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="98"/>
<source>Rotational Angle</source>
- <translation type="unfinished"/>
+ <translation>Forgásszög</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="132"/>
<source>Restore Defaults</source>
- <translation>Visszaállítás alapértelmezettre</translation>
+ <translation>Visszaállítás</translation>
</message>
</context>
<context>
@@ -3231,7 +3228,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_ui.cpp" line="36"/>
<source>Standard (64x64)</source>
- <translation type="unfinished"/>
+ <translation>Szabványos (64x64)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.cpp" line="37"/>
@@ -3251,7 +3248,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_ui.cpp" line="44"/>
<source>Standard (48x48)</source>
- <translation type="unfinished"/>
+ <translation>Szabványos (48x48)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.cpp" line="45"/>
@@ -3284,7 +3281,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="17"/>
@@ -3299,7 +3296,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="31"/>
<source>Note: Changing language will apply your configuration.</source>
- <translation type="unfinished"/>
+ <translation>Megjegyzés: A nyelvváltoztatás azonnal érvénybe lép.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="43"/>
@@ -3337,70 +3334,75 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Fájltípus oszlop mutatása</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>Játékidő oszlop mutatása</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Játék ikonméret:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Mappa ikonméret:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>1. sor szövege:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>2. sor szövege:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Képernyőmentések</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Kérdezze meg a képernyőmentések útvonalát (csak Windowson)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Képernyőmentések útvonala:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Felbontás:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Képernyőmentések útvonala...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
- <translation>Auto (%1 x %2, %3 x %4)</translation>
+ <translation>Automatikus (%1 x %2, %3 x %4)</translation>
</message>
</context>
<context>
@@ -3488,7 +3490,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="14"/>
<source>Form</source>
- <translation type="unfinished"/>
+ <translation>Forma</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="17"/>
@@ -3529,7 +3531,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="93"/>
<source>What is my token?</source>
- <translation type="unfinished"/>
+ <translation>Mi a tokenem?</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
@@ -3584,7 +3586,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="76"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/wiki/yuzu-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;a href=&apos;https://yuzu-emu.org/wiki/yuzu-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Mi a tokenem?&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="80"/>
@@ -3596,23 +3598,23 @@ Drag points to change position, or double-click table cells to edit values.</sou
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
- <translation type="unfinished"/>
+ <translation>Nem meghatározott</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="117"/>
<source>Token not verified</source>
- <translation type="unfinished"/>
+ <translation>Token nincs megerősítve</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="118"/>
<source>Token was not verified. The change to your token has not been saved.</source>
- <translation type="unfinished"/>
+ <translation>Token nincs megerősítve. A változtatások nem lettek elmentve.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
<source>Unverified, please click Verify before saving configuration</source>
<comment>Tooltip</comment>
- <translation type="unfinished"/>
+ <translation>Nincs megerősítve, kattints a Megerősítés gombra mielőtt elmentenéd a konfigurációt</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
@@ -3640,7 +3642,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
- <translation>Sikertelen megerősítése. Győződj meg róla, hogy helyesen írtad be a tokened, és van internetkapcsolatod.</translation>
+ <translation>Sikertelen megerősítés. Győződj meg róla, hogy helyesen írtad be a tokened, és van internetkapcsolatod.</translation>
</message>
</context>
<context>
@@ -3661,7 +3663,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="14"/>
<source>Direct Connect</source>
- <translation>Közvetlen kapcsolat</translation>
+ <translation>Közvetlen kapcsolódás</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="47"/>
@@ -3715,959 +3717,998 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
- <translation type="unfinished"/>
+ <translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Névtelen adatok begyűjtve&lt;/a&gt; a yuzu fejlesztésének segítéséhez. &lt;br/&gt;&lt;br/&gt;Szeretnéd megosztani velünk a felhasználási adataidat?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Hibás Vulkan telepítés észlelve</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>A Vulkan inicializálása sikertelen volt az indulás során. &lt;br&gt;&lt;br&gt;Kattints ide&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;a probléma megoldásához szükséges instrukciókhoz&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Játék közben</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
- <translation>Webalkalmazás betöltése...</translation>
+ <translation>Web applet betöltése...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
- <translation>Webalkalmazás letiltása</translation>
+ <translation>Web applet letiltása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
- <translation type="unfinished"/>
+ <translation>A jelenleg készülő árnyékolók mennyisége</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
- <translation type="unfinished"/>
+ <translation>Jelenlegi emuláció sebessége. 100%-nál magasabb vagy alacsonyabb érték azt jelzi, hogy mennyivel gyorsabb vagy lassabb a Switch-nél.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
- <translation type="unfinished"/>
+ <translation>A másodpercenként megjelenített képkockák számát mutatja. Ez játékonként és jelenetenként eltérő lehet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
- <translation type="unfinished"/>
+ <translation>Egy Switch-kép emulálásához szükséges idő, képkockaszám-korlátozás és v-sync nélkül. Teljes sebességű emulálás esetén ennek legfeljebb 16.67 ms-nak kell lennie.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Némítás feloldása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Némítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Hangerő visszaállítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Legutóbbi fájlok törlése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Emulált egér engedélyezve</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Folytatás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Szünet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Figyelmeztetés: Elavult játékformátum</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Hiba történt a ROM betöltése során!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>A ROM formátum nem támogatott.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
- <translation type="unfinished"/>
+ <translation>Hiba történt a videómag inicializálásakor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Hiba történt a ROM betöltése során! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ismeretlen hiba történt. Nyisd meg a logot a részletekért.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Szoftver bezárása...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Mentett adat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Modolt adat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Hiba törént a(z) %1 mappa megnyitása során</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>A mappa nem létezik!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Nem sikerült létrehozni az árnyékoló gyorsítótár könyvtárat ehhez a játékhoz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Hiba történt a játéktartalom eltávolítása során</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Hiba történt a frissítés eltávolítása során</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Hiba történt a DLC eltávolítása során</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Törlöd a telepített játéktartalmat?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Törlöd a telepített játékfrissítést?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Törlöd a telepített DLC-t?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Bejegyzés törlése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Sikeresen eltávolítva</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>A telepített alapjáték sikeresen el lett távolítva.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Az alapjáték nincs telepítve a NAND-ra, ezért nem törölhető.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>A telepített frissítés sikeresen el lett távolítva.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Nincs telepítve frissítés ehhez a játékhoz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Nincs telepítve DLC ehhez a játékhoz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 telepített DLC sikeresen eltávolítva.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Törlöd az egyéni játék konfigurációt?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Törlöd a gyorsítótárat?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Fájl eltávolítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>Játékidő törlése</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>Visszaállítod a játékidőt?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
- <translation type="unfinished"/>
+ <translation>Ehhez a játékhoz nem létezik árnyékoló gyorsítótár.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Hiba történt az egyéni konfiguráció törlése során</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Nem létezik egyéni konfiguráció ehhez a játékhoz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Egyéni játék konfiguráció sikeresen eltávolítva.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Nem sikerült eltávolítani az egyéni játék konfigurációt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS kicsomagolása sikertelen!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Hiba történt a RomFS fájlok másolása közben, vagy a felhasználó megszakította a műveletet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Teljes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Csontváz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>RomFS kicsomagolása...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Mégse</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
- <translation type="unfinished"/>
+ <translation>RomFS kibontása sikeres volt!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>A művelet sikeresen végrehajtva.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
- <translation type="unfinished"/>
+ <translation>Az integritás ellenőrzését nem lehetett elvégezni!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
- <translation type="unfinished"/>
+ <translation>A fájl tartalmának érvényessége nem lett ellenőrizve.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
- <translation type="unfinished"/>
+ <translation>Az integritás ellenőrzése sikertelen!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
- <translation type="unfinished"/>
+ <translation>A fájl tartalma sérült lehet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
- <translation type="unfinished"/>
+ <translation>Integritás ellenőrzése...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
- <translation type="unfinished"/>
+ <translation>Integritás ellenőrzése sikeres!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Parancsikon létrehozása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"/>
+ <translation>Ez létrehoz egy parancsikont az aktuális AppImage-hez. Frissítés után nem garantált a helyes működése. Folytatod?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>Nem hozható létre parancsikon. Ez az útvonal nem létezik &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Ikon létrehozása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation type="unfinished"/>
+ <translation>Nem hozható létre az ikonfájl. Az útvonal &quot;%1&quot; nem létezik és nem is hozható létre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
- <translation type="unfinished"/>
+ <translation>%1 indítása a yuzu Emulátorral</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
- <translation type="unfinished"/>
+ <translation>Nem sikerült létrehozni ezt a parancsikont %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
- <translation type="unfinished"/>
+ <translation>Parancsikon sikeresen létrehozva ide %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
- <translation type="unfinished"/>
+ <translation>Hiba a %1 megnyitásakor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Könyvtár kiválasztása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Tulajdonságok</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
- <translation type="unfinished"/>
+ <translation>A játék tulajdonságait nem sikerült betölteni.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
- <translation type="unfinished"/>
+ <translation>Switch állományok(%1);;Minden fájl (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Fájl betöltése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
- <translation type="unfinished"/>
+ <translation>Kicsomagolt ROM könyvár megnyitása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Érvénytelen könyvtár kiválasztva</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
- <translation type="unfinished"/>
+ <translation>A kiválasztott könyvtár nem tartalmaz &apos;main&apos; fájlt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
- <translation type="unfinished"/>
+ <translation>Telepíthető Switch fájl (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Fájlok telepítése</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>&quot;%1&quot; fájl telepítése...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Telepítés eredménye</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Rendszeralkalmazás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
- <translation type="unfinished"/>
+ <translation>Rendszerarchívum</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
- <translation type="unfinished"/>
+ <translation>Rendszeralkalmazás frissítés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
- <translation type="unfinished"/>
+ <translation>Firmware csomag (A típus)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
- <translation type="unfinished"/>
+ <translation>Firmware csomag (B típus)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Játék</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Játékfrissítés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Játék DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
- <translation type="unfinished"/>
+ <translation>NCA telepítési típus kiválasztása...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
- <translation type="unfinished"/>
+ <translation>Kérjük, válaszd ki, hogy milyen típusú címként szeretnéd telepíteni ezt az NCA-t:
+(A legtöbb esetben az alapértelmezett &quot;Játék&quot; megfelelő.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
- <translation type="unfinished"/>
+ <translation>Nem sikerült telepíteni</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
- <translation type="unfinished"/>
+ <translation>Az NCA-hoz kiválasztott címtípus érvénytelen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Fájl nem található</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>&quot;%1&quot; fájl nem található</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
- <translation type="unfinished"/>
+ <translation>A hardverkövetelmények nem teljesülnek</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
- <translation type="unfinished"/>
+ <translation>Az eszközöd nem felel meg az ajánlott hardverkövetelményeknek. A kompatibilitás jelentése letiltásra került.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
- <translation type="unfinished"/>
+ <translation>Hiányzó yuzu fiók</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Hiba történt az URL megnyitása során</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Hiba történt az URL megnyitása során: &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
- <translation type="unfinished"/>
+ <translation>TAS felvétel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
- <translation type="unfinished"/>
+ <translation>Felülírod az 1. játékos fájlját?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Érvénytelen konfig észlelve</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
- <translation type="unfinished"/>
+ <translation>A kézi vezérlés nem használható dokkolt módban. Helyette a Pro kontroller lesz kiválasztva.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
- <translation type="unfinished"/>
+ <translation>A jelenlegi amiibo el lett távolítva</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Hiba</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
- <translation type="unfinished"/>
+ <translation>A jelenlegi játék nem keres amiibo-kat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo fájl (%1);; Minden fájl (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Amiibo betöltése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
- <translation type="unfinished"/>
+ <translation>Amiibo adatok betöltése sikertelen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
- <translation type="unfinished"/>
+ <translation>A kiválasztott fájl nem érvényes amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>A kiválasztott fájl már használatban van</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Ismeretlen hiba történt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
- <translation type="unfinished"/>
+ <translation>Az alábbi fájlok ellenőrzése sikertelen volt:
+
+%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
- <translation type="unfinished"/>
+ <translation>Nincs elérhető firmware</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>Kérjük, telepítsd a firmware-t az Album applet használatához.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>Album applet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>Album applet nem elérhető. Kérjük, telepítsd újra a firmware-t.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>Kérjük, telepítsd a firmware-t a kabinet applet használatához.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Kabinet applet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>Kabinet applet nem elérhető. Kérjük, telepítsd újra a firmware-t.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
- <translation type="unfinished"/>
+ <translation>Kérjük, telepítsd a firmware-t a Mii-szerkesztő használatához.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
- <translation type="unfinished"/>
+ <translation>Mii szerkesztő applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
- <translation type="unfinished"/>
+ <translation>A Mii szerkesztő nem elérhető. Kérjük, telepítsd újra a firmware-t.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Képernyőkép készítése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG kép (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
- <translation type="unfinished"/>
+ <translation>TAS állapot: %1/%2 futtatása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
- <translation type="unfinished"/>
+ <translation>TAS állapot: %1 felvétele</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
- <translation type="unfinished"/>
+ <translation>TAS állapot: Tétlen %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
- <translation type="unfinished"/>
+ <translation>TAS állapot: Érvénytelen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
- <translation type="unfinished"/>
+ <translation>&amp;Futás leállítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Indítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>F&amp;elvétel leállítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>F&amp;elvétel</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skálázás: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Sebesség: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Sebesség: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Játék: %1 FPS (Feloldva)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Játék: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Képkocka: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>Nincs élsimítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>HANGERŐ: NÉMÍTVA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>HANGERŐ: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
- <translation type="unfinished"/>
+ <translation>Kulcs újragenerálásának megerősítése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4675,93 +4716,103 @@ Please make sure this is what you want
and optionally make backups.
This will delete your autogenerated key files and re-run the key derivation module.</source>
- <translation type="unfinished"/>
+ <translation>Épp az összes kulcs kényszerített újragenerálására készülsz.
+Ha nem tudod, mit jelent, vagy mit csinálsz,
+ez egy potenciálisan veszélyes művelet.
+Kérljük, győződj meg róla, hogy ezt szeretnéd,
+és opcionálisan készíts biztonsági másolatot.
+
+Ez törli az automatikusan generált kulcsfájlokat, és újraindítja a kulcsgeneráló modult.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - Hiányzó BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Hiányzó BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Hiányzó PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
- <translation type="unfinished"/>
+ <translation>Hiányzó titkosítási kulcsok. &lt;br&gt;Kérjük, kövesd a &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu gyorstájékoztatóját&lt;/a&gt;, hogy megszerezd az összes kulcsot, firmware-t és játékot.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
- <translation type="unfinished"/>
+ <translation>Kulcsok generálása...
+Ez akár egy percet is igénybe vehet,
+rendszered teljesítményétől függően.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
- <translation type="unfinished"/>
+ <translation>Kulcsok generálása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
- <translation type="unfinished"/>
+ <translation>Rendszerarchívum visszafejtése sikertelen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Biztosan be akarod zárni a yuzut?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
- <translation type="unfinished"/>
+ <translation>Biztos le akarod állítani az emulációt? Minden nem mentett adat el fog veszni.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
- <translation type="unfinished"/>
+ <translation>Az éppen futó alkalmazás azt kérte a yuzu-tól, hogy ne lépjen ki.
+
+Mégis ki szeretnél lépni?</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="71"/>
@@ -4806,7 +4857,7 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>Docked</source>
- <translation>Dokkolva</translation>
+ <translation>Dokkolt</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
@@ -4901,247 +4952,257 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/bootmanager.cpp" line="1028"/>
<source>Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.&lt;br&gt;&lt;br&gt;GL Renderer:&lt;br&gt;%1&lt;br&gt;&lt;br&gt;Unsupported extensions:&lt;br&gt;%2</source>
- <translation type="unfinished"/>
+ <translation>Előfordulhat, hogy a GPU-d nem támogat egy vagy több szükséges OpenGL kiterjesztést. Győződj meg róla, hogy a legújabb videokártya-illesztőprogramot használod.&lt;br&gt;&lt;br&gt;GL Renderer:&lt;br&gt;%1&lt;br&gt;&lt;br&gt;Nem támogatott kiterjesztések:&lt;br&gt;%2</translation>
</message>
</context>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Kedvenc</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Játék indítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Játék indítása egyéni konfiguráció nélkül</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Eltávolítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Telepített frissítés eltávolítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Összes telepített DLC eltávolítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Egyéni konfiguráció eltávolítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>Játékidő törlése</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Gyorsítótár ürítése</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>OpenGL Pipeline gyorsítótár eltávolítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
- <translation>Vulkan Pipeline gyorsítótár eltávolítása</translation>
+ <translation>Vulkan pipeline gyorsítótár eltávolítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Az összes Pipeline gyorsítótár törlése</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Összes telepített tartalom törlése</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
- <translation type="unfinished"/>
+ <translation>RomFS kimentése</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
- <translation type="unfinished"/>
+ <translation>RomFS kimentése SDMC-re</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Integritás ellenőrzése</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Játék címének vágólapra másolása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
- <translation type="unfinished"/>
+ <translation>GameDB bejegyzéshez navigálás</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Parancsikon létrehozása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Asztalhoz adás</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Alkalmazások menühöz adás</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Tulajdonságok</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Almappák szkennelése</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
- <translation type="unfinished"/>
+ <translation>Játékkönyvtár eltávolítása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
- <translation type="unfinished"/>
+ <translation>▲ Feljebb mozgatás</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
- <translation type="unfinished"/>
+ <translation>▼ Lejjebb mozgatás</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
- <translation type="unfinished"/>
+ <translation>Könyvtár helyének megnyitása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Törlés</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Név</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatibilitás</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Kiegészítők</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Fájltípus</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Méret</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>Játékidő</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Játékban</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
- <translation type="unfinished"/>
+ <translation>A játék elindul, de összeomlik, vagy súlyos hibák miatt nem fejezhető be.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Tökéletes</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>A játék problémamentesen játszható.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Játszható</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>A játék kisebb grafikai- és hanghibákkal végigjátszható.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Bevezető/Menü</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
- <translation type="unfinished"/>
+ <translation>A játék betölt, de nem jut tovább a Kezdőképernyőn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Nem indul</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
- <translation type="unfinished"/>
+ <translation>A játék összeomlik indításkor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Nem tesztelt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Ez a játék még nem lett tesztelve.</translation>
</message>
@@ -5149,9 +5210,9 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
- <translation type="unfinished"/>
+ <translation>Dupla kattintással új mappát adhatsz hozzá a játéklistához.</translation>
</message>
</context>
<context>
@@ -5162,14 +5223,14 @@ Would you like to bypass this and exit anyway?</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Szűrés:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
- <translation type="unfinished"/>
+ <translation>Adj meg egy mintát a szűréshez</translation>
</message>
</context>
<context>
@@ -5187,7 +5248,7 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="51"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>Preferált játék</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="61"/>
@@ -5237,7 +5298,7 @@ Would you like to bypass this and exit anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
<source>Host Room</source>
- <translation type="unfinished"/>
+ <translation>Szoba létrehozása</translation>
</message>
</context>
<context>
@@ -5251,7 +5312,8 @@ Would you like to bypass this and exit anyway?</source>
<location filename="../../src/yuzu/multiplayer/host_room.cpp" line="186"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>Nem sikerült bejelenteni a szobát a nyilvános lobbiban. Ahhoz, hogy egy szobát nyilvánosan létrehozhass, érvényes yuzu-fiókkal kell rendelkezned, amelyet az Emuláció -&gt; Konfigurálás -&gt; Web menüpontban kell beállítanod. Ha nem szeretnél egy szobát közzétenni a nyilvános lobbiban, akkor válaszd helyette a Nem listázott lehetőséget.
+Hibakereső üzenet:</translation>
</message>
</context>
<context>
@@ -5284,6 +5346,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Főablak</translation>
</message>
@@ -5305,22 +5368,22 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="122"/>
<source>Change Adapting Filter</source>
- <translation type="unfinished"/>
+ <translation>Alkalmazkodó szűrő módosítása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="123"/>
<source>Change Docked Mode</source>
- <translation type="unfinished"/>
+ <translation>Dokkolt mód módosítása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="124"/>
<source>Change GPU Accuracy</source>
- <translation type="unfinished"/>
+ <translation>GPU pontosság módosítása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="125"/>
<source>Continue/Pause Emulation</source>
- <translation type="unfinished"/>
+ <translation>Emuláció folytatása/szüneteltetése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="126"/>
@@ -5345,7 +5408,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="130"/>
<source>Load/Remove Amiibo</source>
- <translation type="unfinished"/>
+ <translation>Amiibo betöltése/törlése</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="131"/>
@@ -5360,17 +5423,17 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="133"/>
<source>TAS Record</source>
- <translation type="unfinished"/>
+ <translation>TAS felvétel</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="134"/>
<source>TAS Reset</source>
- <translation type="unfinished"/>
+ <translation>TAS visszaállítása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="135"/>
<source>TAS Start/Stop</source>
- <translation type="unfinished"/>
+ <translation>TAS indítása/leállítása</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="136"/>
@@ -5380,15 +5443,20 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<source>Toggle Framerate Limit</source>
- <translation type="unfinished"/>
+ <translation>Képfrissítési korlát kapcsoló</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<source>Toggle Mouse Panning</source>
- <translation type="unfinished"/>
+ <translation>Egérpásztázás kapcsoló</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Állapotsáv kapcsoló</translation>
</message>
@@ -5398,12 +5466,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/install_dialog.cpp" line="29"/>
<source>Please confirm these are the files you wish to install.</source>
- <translation type="unfinished"/>
+ <translation>Kérjük, erősítsd meg, hogy ezeket a fájlokat szeretnéd telepíteni.</translation>
</message>
<message>
<location filename="../../src/yuzu/install_dialog.cpp" line="32"/>
<source>Installing an Update or DLC will overwrite the previously installed one.</source>
- <translation type="unfinished"/>
+ <translation>Egy frissítés vagy DLC telepítése felülírja a korábban telepítettet.</translation>
</message>
<message>
<location filename="../../src/yuzu/install_dialog.cpp" line="36"/>
@@ -5422,7 +5490,8 @@ Debug Message: </source>
<location filename="../../src/yuzu/util/limitable_input_dialog.cpp" line="59"/>
<source>The text can't contain any of the following characters:
%1</source>
- <translation type="unfinished"/>
+ <translation>A szöveg nem tartalmazhatja a következő karakterek egyikét sem:
+%1</translation>
</message>
</context>
<context>
@@ -5435,7 +5504,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/loading_screen.ui" line="121"/>
<source>Loading Shaders %v out of %m</source>
- <translation>Loading Shaders %v out of %m</translation>
+ <translation>Árnyékolók betöltése %v / %m</translation>
</message>
<message>
<location filename="../../src/yuzu/loading_screen.ui" line="135"/>
@@ -5468,7 +5537,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="14"/>
<source>Public Room Browser</source>
- <translation type="unfinished"/>
+ <translation>Nyilvános szoba böngésző</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="32"/>
@@ -5529,12 +5598,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.cpp" line="219"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>Preferált játék</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.cpp" line="220"/>
<source>Host</source>
- <translation>Hoszt</translation>
+ <translation>Házigazda</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.cpp" line="227"/>
@@ -5567,7 +5636,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="66"/>
<source>&amp;Emulation</source>
- <translation type="unfinished"/>
+ <translation>&amp;Emuláció</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="77"/>
@@ -5626,186 +5695,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Segítség</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
- <translation type="unfinished"/>
+ <translation>&amp;Fájlok telepítése a NAND-ra...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
- <translation type="unfinished"/>
+ <translation>F&amp;ájl betöltése...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
- <translation type="unfinished"/>
+ <translation>&amp;Mappa betöltése...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>K&amp;ilépés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Szünet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Leállítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
- <translation type="unfinished"/>
+ <translation>&amp;Kulcsok újraaktiválása...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>&amp;Telepített tartalom ellenőrzése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;A yuzuról</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
- <translation type="unfinished"/>
+ <translation>&amp;Egyablakos mód</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
- <translation>Kon@figurálás</translation>
+ <translation>Kon&amp;figurálás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
- <translation type="unfinished"/>
+ <translation>D&amp;ock Widget fejlécek megjelenítése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>&amp;Szűrősáv mutatása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>&amp;Állapotsáv mutatása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Állapotsáv mutatása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Nyilvános játéklobbi böngészése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Szoba létrehozása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Szoba elhagyása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
- <translation type="unfinished"/>
+ <translation>&amp;Közvetlen csatlakozás a szobához</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
- <translation type="unfinished"/>
+ <translation>&amp;Jelenlegi szoba megjelenítése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
- <translation>T@eljes képernyő</translation>
+ <translation>T&amp;eljes képernyő</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Újraindítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>&amp;Amiibo betöltése/törlése...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Kompatibilitás jelentése</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>&amp;Módok oldal megnyitása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
- <translation type="unfinished"/>
+ <translation>&amp;Gyorstájékoztató megnyitása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;GYIK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>&amp;yuzu mappa megnyitása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
- <translation type="unfinished"/>
+ <translation>&amp;Képernyőkép készítése</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>&amp;Album megnyitása</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>&amp;Becenév és tulajdonos beállítása</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>&amp;Játékadatok törlése</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>&amp;Amiibo helyreállítása</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>&amp;Amiibo formázása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
- <translation type="unfinished"/>
+ <translation>&amp;Mii szerkesztő megnyitása</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
- <translation type="unfinished"/>
+ <translation>&amp;TAS konfigurálása...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
- <translation type="unfinished"/>
+ <translation>J&amp;elenlegi játék konfigurálása...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Indítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Visszaállítás</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>F&amp;elvétel</translation>
</message>
@@ -5815,7 +5914,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/debugger/profiler.cpp" line="50"/>
<source>&amp;MicroProfile</source>
- <translation type="unfinished"/>
+ <translation>&amp;Mikroprofil</translation>
</message>
</context>
<context>
@@ -5903,7 +6002,8 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="208"/>
<source>Failed to update the room information. Please check your Internet connection and try hosting the room again.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>Nem sikerült frissíteni a szoba adatait. Kérjük, ellenőrizd az internetkapcsolatot, és próbáld újra a szoba létrehozását.
+Hibakereső üzenet:</translation>
</message>
</context>
<context>
@@ -5931,22 +6031,22 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="19"/>
<source>Port must be a number between 0 to 65535.</source>
- <translation type="unfinished"/>
+ <translation>A port csak 0 és 65535 közötti szám lehet.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
<source>You must choose a Preferred Game to host a room. If you do not have any games in your game list yet, add a game folder by clicking on the plus icon in the game list.</source>
- <translation type="unfinished"/>
+ <translation>A szoba létrehozásához ki kell választanod egy Preferált játékot. Ha még nem szerepel a listádban egyetlen játék sem, adj hozzá egy játékmappát a játéklistában a plusz ikonra kattintva.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
<source>Unable to find an internet connection. Check your internet settings.</source>
- <translation type="unfinished"/>
+ <translation>Nem található internetkapcsolat. Ellenőrizd az internetbeállításokat.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="26"/>
<source>Unable to connect to the host. Verify that the connection settings are correct. If you still cannot connect, contact the room host and verify that the host is properly configured with the external port forwarded.</source>
- <translation type="unfinished"/>
+ <translation>Nem sikerült csatlakozni a házigazdához. Ellenőrizd, hogy a kapcsolat beállításai helyesek-e. Ha még mindig nem tudsz csatlakozni, lépj kapcsolatba a gazdával, hogy ellenőrizze, megfelelően van-e konfigurálva a külső port továbbítása.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="30"/>
@@ -5956,17 +6056,17 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="32"/>
<source>Creating a room failed. Please retry. Restarting yuzu might be necessary.</source>
- <translation type="unfinished"/>
+ <translation>Szoba létrehozása sikertelen. Próbáld újra. A yuzu újraindítására szükség lehet.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
<source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
- <translation type="unfinished"/>
+ <translation>A szoba házigazdája kitiltott téged. Beszélj a házigazdával, hogy feloldjon téged, vagy csatlakozz másik szobához.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
<source>Version mismatch! Please update to the latest version of yuzu. If the problem persists, contact the room host and ask them to update the server.</source>
- <translation type="unfinished"/>
+ <translation>Verzió eltérés! Kérjük, frissítsd a yuzut a legújabb verzióra. Ha a probléma továbbra is fennáll, vedd fel a kapcsolatot a házigazdával és kérd meg, hogy frissítse a szervert.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
@@ -5976,39 +6076,41 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="40"/>
<source>An unknown error occurred. If this error continues to occur, please open an issue</source>
- <translation type="unfinished"/>
+ <translation>Ismeretlen hiba történt. Amennyiben a hiba továbbra is fennáll, nyiss egy hibajegyet.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
<source>Connection to room lost. Try to reconnect.</source>
- <translation type="unfinished"/>
+ <translation>Megszakadt a kapcsolat a szobával. Próbálj újracsatlakozni.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
<source>You have been kicked by the room host.</source>
- <translation type="unfinished"/>
+ <translation>A szoba házigazdája kirúgott téged.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
<source>IP address is already in use. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>Az IP-cím már használatban van. Kérjük, válassz egy másikat.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
<source>You do not have enough permission to perform this action.</source>
- <translation type="unfinished"/>
+ <translation>Nincs elég jogosultságod a művelet végrehajtásához.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="50"/>
<source>The user you are trying to kick/ban could not be found.
They may have left the room.</source>
- <translation type="unfinished"/>
+ <translation>A felhasználó, akit ki akarsz rúgni/tiltani, nem található.
+Lehet, hogy elhagyta a szobát.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="52"/>
<source>No valid network interface is selected.
Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
- <translation type="unfinished"/>
+ <translation>Nincs kiválasztva érvényes hálózati adapter.
+Látogasd meg a Konfigurálás -&gt; Rendszer -&gt; Hálózat menüpontokat a beállításhoz.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
@@ -6019,7 +6121,8 @@ Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
<source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
Proceed anyway?</source>
- <translation type="unfinished"/>
+ <translation>Már játékban lévő szobához való csatlakozás nem ajánlott, és problémákat okozhat a szoba funkcióinak működésében.
+Mindenképp folytatod?</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
@@ -6029,7 +6132,7 @@ Proceed anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>Éppen készülsz bezárni a szobát. Minden hálózati kapcsolat lezárul.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
@@ -6039,7 +6142,7 @@ Proceed anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>Éppen készülsz elhagyni a szobát. Minden hálózati kapcsolat lezárul.</translation>
</message>
</context>
<context>
@@ -6055,7 +6158,7 @@ Proceed anyway?</source>
<message>
<location filename="../../src/yuzu/util/overlay_dialog.ui" line="14"/>
<source>Dialog</source>
- <translation type="unfinished"/>
+ <translation>Párbeszéd</translation>
</message>
<message>
<location filename="../../src/yuzu/util/overlay_dialog.ui" line="134"/>
@@ -6076,7 +6179,11 @@ Proceed anyway?</source>
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:18pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:18pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
</context>
<context>
@@ -6105,27 +6212,27 @@ p, li { white-space: pre-wrap; }
<translation>Nincs játékban</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
- <translation type="unfinished"/>
+ <translation>Telepített SD játékok</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
- <translation type="unfinished"/>
+ <translation>Telepített NAND játékok</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
- <translation type="unfinished"/>
+ <translation>Rendszercímek</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
- <translation type="unfinished"/>
+ <translation>Új játékkönyvtár hozzáadása</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Kedvencek</translation>
</message>
@@ -6134,21 +6241,21 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="32"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="43"/>
<source>Shift</source>
- <translation type="unfinished"/>
+ <translation>Shift</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="23"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="34"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="45"/>
<source>Ctrl</source>
- <translation type="unfinished"/>
+ <translation>Ctrl</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="25"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="36"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="47"/>
<source>Alt</source>
- <translation type="unfinished"/>
+ <translation>Alt</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="35"/>
@@ -6157,7 +6264,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="181"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
<source>[not set]</source>
- <translation>[nincs beállítva]</translation>
+ <translation>[nincs beáll.]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="47"/>
@@ -6175,12 +6282,12 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="280"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="284"/>
<source>Axis %1%2</source>
- <translation type="unfinished"/>
+ <translation>Tengely %1%2</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="60"/>
<source>Button %1</source>
- <translation type="unfinished"/>
+ <translation>Gomb %1</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="66"/>
@@ -6191,7 +6298,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="287"/>
<source>[unknown]</source>
- <translation type="unfinished"/>
+ <translation>[ismeretlen]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="47"/>
@@ -6225,31 +6332,31 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="55"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="66"/>
<source>Z</source>
- <translation type="unfinished"/>
+ <translation>Z</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="57"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="68"/>
<source>R</source>
- <translation type="unfinished"/>
+ <translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="59"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="70"/>
<source>L</source>
- <translation type="unfinished"/>
+ <translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="61"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="84"/>
<source>A</source>
- <translation type="unfinished"/>
+ <translation>A</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="63"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="86"/>
<source>B</source>
- <translation type="unfinished"/>
+ <translation>B</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="65"/>
@@ -6267,43 +6374,43 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="69"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="92"/>
<source>Start</source>
- <translation type="unfinished"/>
+ <translation>Start</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="71"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="102"/>
<source>L1</source>
- <translation type="unfinished"/>
+ <translation>L1</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="104"/>
<source>L2</source>
- <translation type="unfinished"/>
+ <translation>L2</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="106"/>
<source>L3</source>
- <translation type="unfinished"/>
+ <translation>L3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="77"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="108"/>
<source>R1</source>
- <translation type="unfinished"/>
+ <translation>R1</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="79"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="110"/>
<source>R2</source>
- <translation type="unfinished"/>
+ <translation>R2</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="81"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="112"/>
<source>R3</source>
- <translation type="unfinished"/>
+ <translation>R3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="83"/>
@@ -6345,18 +6452,18 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="95"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="140"/>
<source>[undefined]</source>
- <translation type="unfinished"/>
+ <translation>[nem definiált]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
<source>%1%2</source>
- <translation type="unfinished"/>
+ <translation>%1%2</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="406"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
<source>[invalid]</source>
- <translation type="unfinished"/>
+ <translation>[érvénytelen]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="416"/>
@@ -6370,13 +6477,13 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="446"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="237"/>
<source>%1%2Axis %3</source>
- <translation type="unfinished"/>
+ <translation>%1%2Tengely %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="426"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Axis %3,%4,%5</source>
- <translation type="unfinished"/>
+ <translation>%1%2Tengely %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="430"/>
@@ -6388,13 +6495,13 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="434"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="449"/>
<source>%1%2Button %3</source>
- <translation type="unfinished"/>
+ <translation>%1%2Gomb %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="476"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="267"/>
<source>[unused]</source>
- <translation type="unfinished"/>
+ <translation>[nem használt]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="72"/>
@@ -6429,12 +6536,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="94"/>
<source>Plus</source>
- <translation type="unfinished"/>
+ <translation>Plusz</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="96"/>
<source>Minus</source>
- <translation type="unfinished"/>
+ <translation>Mínusz</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="98"/>
@@ -6461,27 +6568,27 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="132"/>
<source>Backward</source>
- <translation type="unfinished"/>
+ <translation>Hátra</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="134"/>
<source>Forward</source>
- <translation type="unfinished"/>
+ <translation>Előre</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="136"/>
<source>Task</source>
- <translation type="unfinished"/>
+ <translation>Feladat</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="138"/>
<source>Extra</source>
- <translation type="unfinished"/>
+ <translation>Extra</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
<source>%1%2%3%4</source>
- <translation type="unfinished"/>
+ <translation>%1%2%3%4</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
@@ -6493,13 +6600,13 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
<source>%1%2%3Axis %4</source>
- <translation type="unfinished"/>
+ <translation>%1%2%3Tengely %4</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="240"/>
<source>%1%2%3Button %4</source>
- <translation type="unfinished"/>
+ <translation>%1%2%3Gomb %4</translation>
</message>
</context>
<context>
@@ -6507,12 +6614,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.ui" line="14"/>
<source>Amiibo Settings</source>
- <translation type="unfinished"/>
+ <translation>Amiibo beállítások</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.ui" line="169"/>
<source>Amiibo Info</source>
- <translation type="unfinished"/>
+ <translation>Amiibo infó</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.ui" line="177"/>
@@ -6532,7 +6639,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.ui" line="242"/>
<source>Amiibo Data</source>
- <translation type="unfinished"/>
+ <translation>Amiibo adatok</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.ui" line="250"/>
@@ -6577,7 +6684,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.ui" line="384"/>
<source>Mount Amiibo</source>
- <translation type="unfinished"/>
+ <translation>Amiibo csatolása</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.ui" line="390"/>
@@ -6597,7 +6704,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="232"/>
<source>The following amiibo data will be formatted:</source>
- <translation type="unfinished"/>
+ <translation>Az alábbi amiibo adatok formázva lesznek:</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="235"/>
@@ -6607,12 +6714,12 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="238"/>
<source>Set nickname and owner:</source>
- <translation type="unfinished"/>
+ <translation>Becenév és tulajdonos beállítása:</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_amiibo_settings.cpp" line="241"/>
<source>Do you wish to restore this amiibo?</source>
- <translation type="unfinished"/>
+ <translation>Szeretnéd visszaállítani ezt az amiibót?</translation>
</message>
</context>
<context>
@@ -6620,7 +6727,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="14"/>
<source>Controller Applet</source>
- <translation type="unfinished"/>
+ <translation>Vezérlő applet</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="129"/>
@@ -6640,7 +6747,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="418"/>
<source>P4</source>
- <translation type="unfinished"/>
+ <translation>P4</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="514"/>
@@ -6651,7 +6758,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro kontroller</translation>
</message>
@@ -6664,7 +6771,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation type="unfinished"/>
</message>
@@ -6677,7 +6784,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Bal Joycon</translation>
</message>
@@ -6690,7 +6797,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Jobb Joycon</translation>
</message>
@@ -6719,44 +6826,44 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Kézi</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1126"/>
<source>P3</source>
- <translation type="unfinished"/>
+ <translation>P3</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1363"/>
<source>P7</source>
- <translation type="unfinished"/>
+ <translation>P7</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1560"/>
<source>P8</source>
- <translation type="unfinished"/>
+ <translation>P8</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1757"/>
<source>P5</source>
- <translation type="unfinished"/>
+ <translation>P5</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1958"/>
<source>P6</source>
- <translation type="unfinished"/>
+ <translation>P6</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2272"/>
<source>Console Mode</source>
- <translation>Konzol Mód</translation>
+ <translation>Konzol mód</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2293"/>
<source>Docked</source>
- <translation>Dokkolva</translation>
+ <translation>Dokkolt</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2313"/>
@@ -6787,7 +6894,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2467"/>
<source>Controllers</source>
- <translation>Kontrollerek</translation>
+ <translation>Vezérlők</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2481"/>
@@ -6835,34 +6942,39 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>Nincs elég vezérlő</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
- <translation type="unfinished"/>
+ <translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64 kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
- <translation type="unfinished"/>
+ <translation>Sega Genesis</translation>
</message>
</context>
<context>
@@ -6878,7 +6990,8 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_error.cpp" line="31"/>
<source>An error has occurred.
Please try again or contact the developer of the software.</source>
- <translation type="unfinished"/>
+ <translation>Hiba történt.
+Kérjük, próbáld újra, vagy lépj kapcsolatba a szoftver fejlesztőjével.</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_error.cpp" line="44"/>
@@ -6959,7 +7072,7 @@ Please try again or contact the developer of the software.</source>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="210"/>
<source>Select a user to link to a Nintendo Account.</source>
- <translation type="unfinished"/>
+ <translation>Válassz ki egy felhasználót a Nintendo fiókkal való összekapcsoláshoz.</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="213"/>
@@ -6969,7 +7082,7 @@ Please try again or contact the developer of the software.</source>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="216"/>
<source>Format data for which user?</source>
- <translation type="unfinished"/>
+ <translation>Melyik felhasználó adatait formázzuk?</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="219"/>
@@ -7006,7 +7119,11 @@ Please try again or contact the developer of the software.</source>
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:26pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:26pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_software_keyboard.cpp" line="403"/>
@@ -7046,7 +7163,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="184"/>
<source>waited by no thread</source>
- <translation type="unfinished"/>
+ <translation>nem vár egy szálra sem</translation>
</message>
</context>
<context>
@@ -7064,32 +7181,32 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="210"/>
<source>sleeping</source>
- <translation type="unfinished"/>
+ <translation>alszik</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="213"/>
<source>waiting for IPC reply</source>
- <translation type="unfinished"/>
+ <translation>IPC válaszra várakozás</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="216"/>
<source>waiting for objects</source>
- <translation type="unfinished"/>
+ <translation>várakozás objektumokra</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="219"/>
<source>waiting for condition variable</source>
- <translation type="unfinished"/>
+ <translation>várakozás állapotváltozóra</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="222"/>
<source>waiting for address arbiter</source>
- <translation type="unfinished"/>
+ <translation>várakozás címkiosztásra</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="225"/>
<source>waiting for suspend resume</source>
- <translation type="unfinished"/>
+ <translation>várakozás felfüggesztés folytatására</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="228"/>
@@ -7124,7 +7241,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="297"/>
<source>core %1</source>
- <translation type="unfinished"/>
+ <translation>mag %1</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="301"/>
@@ -7134,22 +7251,22 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="303"/>
<source>affinity mask = %1</source>
- <translation type="unfinished"/>
+ <translation>affinitás maszk = %1</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="304"/>
<source>thread id = %1</source>
- <translation type="unfinished"/>
+ <translation>szál azonosító = %1</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="305"/>
<source>priority = %1(current) / %2(normal)</source>
- <translation type="unfinished"/>
+ <translation>prioritás = %1(jelenleg) / %2(normál)</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="309"/>
<source>last running ticks = %1</source>
- <translation type="unfinished"/>
+ <translation>utolsó futó tickek = %1</translation>
</message>
</context>
<context>
@@ -7157,7 +7274,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="325"/>
<source>waited by thread</source>
- <translation type="unfinished"/>
+ <translation>szálra várakozás</translation>
</message>
</context>
<context>
@@ -7165,7 +7282,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="399"/>
<source>&amp;Wait Tree</source>
- <translation type="unfinished"/>
+ <translation>&amp;Várófa</translation>
</message>
</context>
</TS> \ No newline at end of file
diff --git a/dist/languages/id.ts b/dist/languages/id.ts
index bbf0ed89a..6a1475f13 100644
--- a/dist/languages/id.ts
+++ b/dist/languages/id.ts
@@ -365,13 +365,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -855,49 +855,29 @@ Memungkinkan berbagai macam optimasi IR.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Nyalakan Layanan Laporan Bertele-tele**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Ini akan diatur ulang secara otomatis ketika yuzu ditutup.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu harus dimuat-ulang untuk mengaplikasikan pengaturan ini.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation type="unfinished"/>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation type="unfinished"/>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1316,7 +1296,7 @@ Memungkinkan berbagai macam optimasi IR.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Urutan Tombol yang Konflik</translation>
</message>
@@ -1337,27 +1317,37 @@ Memungkinkan berbagai macam optimasi IR.</translation>
<translation>Tidak valid</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Kembalikan ke Semula</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Bersihkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Urutan tombol bawaan sudah diterapkan ke: %1</translation>
</message>
@@ -3332,67 +3322,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Ukuran Ikon Game:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Ukuran Ikon Folder:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Teks Baris 1:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Teks Baris 2:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Screenshot</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Menanya Dimana Untuk Menyimpan Screenshot (Hanya untuk Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Jalur Screenshot:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Resolusi:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Pilih Jalur Screenshot...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3710,963 +3705,999 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Data anonim dikumpulkan&lt;/a&gt; untuk membantu yuzu. &lt;br/&gt;&lt;br/&gt;Apa Anda ingin membagi data penggunaan dengan kami?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Memuat Applet Web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Matikan Applet Web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Jumlah shader yang sedang dibuat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Pengali skala resolusi yang terpilih.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Kecepatan emulasi saat ini. Nilai yang lebih tinggi atau rendah dari 100% menandakan pengemulasian berjalan lebih cepat atau lambat dibanding Switch aslinya.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Berapa banyak frame per second (bingkai per detik) permainan akan ditampilkan. Ini akan berubah dari berbagai permainan dan pemandangan.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Waktu yang diperlukan untuk mengemulasikan bingkai Switch, tak menghitung pembatas bingkai atau v-sync. Agar emulasi berkecepatan penuh, ini harus 16.67 mdtk.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Membunyikan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Bisukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Atur ulang tingkat suara</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Bersihkan Berkas Baru-baru Ini</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Lanjutkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Jeda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Peringatan Format Permainan yang Usang</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Anda menggunakan format direktori ROM yang sudah didekonstruksi untuk permainan ini, yang mana itu merupakan format lawas yang sudah tergantikan oleh yang lain seperti NCA, NAX, XCI, atau NSP. Direktori ROM yang sudah didekonstruksi kekurangan ikon, metadata, dan dukungan pembaruan.&lt;br&gt;&lt;br&gt;Untuk penjelasan berbagai format Switch yang didukung yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;periksa wiki kami&lt;/a&gt;. Pesan ini tidak akan ditampilkan lagi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Kesalahan ketika memuat ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Format ROM tak didukung.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Terjadi kesalahan ketika menginisialisasi inti video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu telah mengalami error saat menjalankan inti video. Ini biasanya disebabkan oleh pemicu piranti (driver) GPU yang usang, termasuk yang terintegrasi. Mohon lihat catatan untuk informasi lebih rinci. Untuk informasi cara mengakses catatan, mohon lihat halaman berikut: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Cara Mengupload Berkas Catatan&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Terjadi kesalahan yang tak diketahui. Mohon lihat catatan untuk informasi lebih rinci.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Simpan Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Gagal Membuka Folder %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Folder tak ada!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Gagal Ketika Membuka Tembolok Shader yang Dapat Ditransfer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Error saat menghapus konten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Error saat menghapus Update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Error saat menghapus DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Hapus Konten Game yang terinstall?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Hapus Update Game yang terinstall?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Hapus DLC Game yang terinstall?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Hapus Masukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Berhasil menghapus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Tidak ada DLC yang terinstall untuk judul ini.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Hapus File</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Kesalahan Menghapus Transferable Shader Cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Cache shader bagi judul ini tidak ada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Kesalahan Menghapus Konfigurasi Buatan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Pengekstrakan RomFS Gagal!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Terjadi kesalahan ketika menyalin berkas RomFS atau dibatalkan oleh pengguna.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Penuh</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Skeleton</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Pilih Mode Dump RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Mohon pilih cara RomFS akan di-dump.&lt;br&gt;FPenuh akan menyalin seluruh berkas ke dalam direktori baru sementara &lt;br&gt;jerangkong hanya akan menciptakan struktur direktorinya saja.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Mengekstrak RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Batal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Pengekstrakan RomFS Berhasil!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Operasi selesai dengan sukses,</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Buat Pintasan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Buat ikon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Gagal membuka %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Pilih Direktori</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Properti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Properti permainan tak dapat dimuat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Eksekutabel Switch (%1);;Semua Berkas (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Muat Berkas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Buka Direktori ROM Terekstrak</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Direktori Terpilih Tidak Sah</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Direktori yang Anda pilih tak memiliki berkas &apos;utama.&apos;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Install File</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Memasang berkas &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Hasil Install</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n file(s) baru diinstall
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n file(s) telah ditimpa
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n file(s) gagal di install
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Aplikasi Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Arsip Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Pembaruan Aplikasi Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Paket Perangkat Tegar (Tipe A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Paket Perangkat Tegar (Tipe B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Pembaruan Permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC Permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Judul Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Pilih Tipe Pemasangan NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Mohon pilih jenis judul yang Anda ingin pasang sebagai NCA ini:
(Dalam kebanyakan kasus, pilihan bawaan &apos;Permainan&apos; tidak apa-apa`.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Gagal Memasang</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Jenis judul yang Anda pilih untuk NCA tidak sah.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Berkas tak ditemukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Berkas &quot;%1&quot; tak ditemukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Akun yuzu Hilang</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Agar dapat mengirimkan berkas uju kompatibilitas permainan, Anda harus menautkan akun yuzu Anda.&lt;br&gt;&lt;br/&gt;TUntuk mennautkan akun yuzu Anda, pergi ke Emulasi &amp;gt; Konfigurasi &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Kesalahan saat membuka URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Tidak dapat membuka URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Rekaman TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Timpa file pemain 1? </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Konfigurasi tidak sah terdeteksi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Kontroller jinjing tidak bisa digunakan dalam mode dock. Kontroller Pro akan dipilih</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Berkas Amiibo (%1);; Semua Berkas (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Muat Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Gagal memuat data Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Tangkapan Layar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Berkas PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Status TAS: Berjalan %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Status TAS: Merekam %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Status TAS: Diam %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Status TAS: Tidak Valid</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Matikan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Mulai</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Berhenti Mer&amp;ekam</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>R&amp;ekam</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Membangun: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Kecepatan: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Kecepatan: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Permainan: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>TANPA AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUME : SENYAP</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4677,37 +4708,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Kehilangan BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Kehilangan BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- Kehilangan PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4716,49 +4747,49 @@ Ini mungkin memakan waktu hingga satu menit
tergantung dari sistem performa Anda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Pilih Target Dump RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Silahkan pilih jenis RomFS yang ingin Anda buang.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Apakah anda yakin ingin menutup yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Apakah Anda yakin untuk menghentikan emulasi? Setiap progres yang tidak tersimpan akan hilang.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4908,241 +4939,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Favorit</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Mulai permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Buka Lokasi Data Penyimpanan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Buka Lokasi Data Mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Singkirkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Hapus semua konten terinstall.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Dump RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Salin Judul ID ke Clipboard.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Pindah ke tampilan GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Buat pintasan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Menambahkan ke Desktop</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Properti</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Memindai subfolder</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Buka Lokasi Direktori</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Bersihkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nama</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatibilitas</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Pengaya (Add-On)</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Tipe berkas</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Ukuran</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Sempurna</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Permainan dapat dimainkan tanpa kendala.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Awal/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Tidak Akan Berjalan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Gim rusak saat mencoba untuk memulai.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Belum dites</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Gim belum pernah dites.</translation>
</message>
@@ -5150,7 +5191,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Klik dua kali untuk menambahkan folder sebagai daftar permainan.</translation>
</message>
@@ -5163,12 +5204,12 @@ Would you like to bypass this and exit anyway?</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Masukkan pola untuk memfilter</translation>
</message>
@@ -5285,6 +5326,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
@@ -5390,6 +5432,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5627,186 +5674,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Jeda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Munculkan Status Bar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Buka %Panduan cepat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Mulai</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>R&amp;ekam</translation>
</message>
@@ -6106,27 +6183,27 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Tambahkan direktori permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation type="unfinished"/>
</message>
@@ -6652,7 +6729,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Kontroler Pro</translation>
</message>
@@ -6665,7 +6742,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Joycon Dual</translation>
</message>
@@ -6678,7 +6755,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon Kiri</translation>
</message>
@@ -6691,7 +6768,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon Kanan</translation>
</message>
@@ -6720,7 +6797,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Jinjing</translation>
</message>
@@ -6836,32 +6913,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Kontroler GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Kontroler NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Kontroler SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Kontroler N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/it.ts b/dist/languages/it.ts
index 69f39500a..22c6cf912 100644
--- a/dist/languages/it.ts
+++ b/dist/languages/it.ts
@@ -373,13 +373,13 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Automatico (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Predefinito (%1)</translation>
@@ -891,49 +891,29 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Crea Minidump dopo un arresto anomalo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Abilita questa opzione per stampare l&apos;ultima lista dei comandi audio nella console. Impatta solo i giochi che usano il renderer audio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Stampa i comandi audio nella console**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Abilita servizi di segnalazione dettagliata**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**L&apos;opzione verrà automaticamente ripristinata alla chiusura di yuzu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Riavvio richiesto</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu dev&apos;essere riavviato affinché questa opzione venga applicata.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Applet web non compilato</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Creazione MiniDump non compilata</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1352,7 +1332,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Sequenza di tasti in conflitto</translation>
</message>
@@ -1373,27 +1353,37 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<translation>Non valido</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Ripristina predefinita</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Cancella</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Sequenza di pulsanti in conflitto</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>La sequenza di pulsanti predefinita è già assegnata a: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>La sequenza di tasti predefinita è già assegnata a: %1</translation>
</message>
@@ -3375,67 +3365,72 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
<translation>Mostra colonna Tipo di file</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>Mostra Tempo di Gioco</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Dimensione dell&apos;icona del gioco:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Dimensione dell&apos;icona delle cartelle:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Testo riga 1:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Testo riga 2:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Screenshot</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Chiedi dove salvare gli screenshot (solo Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Percorso degli screenshot:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>Etichetta</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Risoluzione:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Seleziona il percorso degli screenshot...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Automatica (%1 x %2, %3 x %4)</translation>
@@ -3753,44 +3748,44 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Vengono raccolti dati anonimi&lt;/a&gt; per aiutarci a migliorare yuzu. &lt;br/&gt;&lt;br/&gt;Desideri condividere i tuoi dati di utilizzo con noi?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Rilevata installazione di Vulkan non funzionante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>L&apos;inizializzazione di Vulkan è fallita durante l&apos;avvio.&lt;br&gt;&lt;br&gt;Clicca &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;qui per istruzioni su come risolvere il problema&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Gioco in esecuzione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Caricamento dell&apos;applet web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Disabilita l&apos;applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Disabilitare l&apos;applet web potrebbe causare dei comportamenti indesiderati.
@@ -3798,570 +3793,574 @@ Da usare solo con Super Mario 3D All-Stars. Sei sicuro di voler procedere?
(Puoi riabilitarlo quando vuoi nelle impostazioni di Debug.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Il numero di shader in fase di compilazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Il moltiplicatore corrente dello scaling della risoluzione.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocità corrente dell&apos;emulazione. Valori più alti o più bassi di 100% indicano che l&apos;emulazione sta funzionando più velocemente o lentamente rispetto a una Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Il numero di fotogrammi al secondo che il gioco visualizza attualmente. Può variare in base al gioco e alla situazione.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tempo necessario per emulare un fotogramma della Switch, senza tenere conto del limite al framerate o del V-Sync. Per un&apos;emulazione alla massima velocità, il valore non dovrebbe essere superiore a 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Riattiva</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Silenzia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Reimposta volume</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Cancella i file recenti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Mouse emulato abilitato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>L&apos;input reale del mouse è incompatibile col mouse panning.
Per attivarlo, disattiva il mouse emulato.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Continua</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Formato del gioco obsoleto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Stai usando una cartella contenente una ROM decostruita per avviare questo gioco, che è un formato obsoleto e sostituito da NCA, NAX, XCI o NSP. Le ROM decostruite non hanno icone, metadati e non supportano gli aggiornamenti. &lt;br&gt;&lt;br&gt;Per una spiegazione sui vari formati della Switch supportati da yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;consulta la nostra wiki (in inglese)&lt;/a&gt;. Non riceverai di nuovo questo avviso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Errore nel caricamento della ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Il formato della ROM non è supportato.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>È stato riscontrato un errore nell&apos;inizializzazione del core video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu ha riscontrato un problema durante l&apos;avvio del core video. Di solito questo errore è causato da driver GPU obsoleti, compresi quelli integrati.
Consulta il log per maggiori dettagli. Se hai bisogno di aiuto per accedere ai log, consulta questa pagina (in inglese): &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Come caricare i file di log&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Errore nel caricamento della ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Segui &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guida introduttiva di yuzu&lt;/a&gt; per rifare il dump dei file.&lt;br&gt;Puoi dare un occhiata alla wiki di yuzu (in inglese)&lt;/a&gt; o al server Discord di yuzu&lt;/a&gt; per assistenza.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Si è verificato un errore sconosciuto. Visualizza il log per maggiori dettagli.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Chiusura del software in corso...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Dati di salvataggio</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Dati delle mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Impossibile aprire la cartella %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>La cartella non esiste!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Impossibile aprire la cache trasferibile degli shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Impossibile creare la cartella della cache degli shader per questo titolo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Impossibile rimuovere il contentuto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Impossibile rimuovere l&apos;aggiornamento</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Impossibile rimuovere il DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Rimuovere il contenuto del gioco installato?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Rimuovere l&apos;aggiornamento installato?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Rimuovere il DLC installato?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Rimuovi voce</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Rimozione completata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Il gioco base installato è stato rimosso con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Il gioco base non è installato su NAND e non può essere rimosso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Aggiornamento rimosso con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Non c&apos;è alcun aggiornamento installato per questo gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Non c&apos;è alcun DLC installato per questo gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 DLC rimossi con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Vuoi rimuovere la cache trasferibile degli shader OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Vuoi rimuovere la cache trasferibile degli shader Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Vuoi rimuovere tutte le cache trasferibili degli shader?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Rimuovere la configurazione personalizzata del gioco?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Rimuovere la Storage Cache?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Rimuovi file</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>Resetta il Tempo di Gioco</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>Davvero?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Impossibile rimuovere la cache trasferibile degli shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Per questo titolo non esiste una cache degli shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>La cache trasferibile degli shader è stata rimossa con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Impossibile rimuovere la cache trasferibile degli shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Impossibile rimuovere la cache delle pipeline del driver Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Impossibile rimuovere la cache delle pipeline del driver.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Impossibile rimuovere le cache trasferibili degli shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Le cache trasferibili degli shader sono state rimosse con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Impossibile rimuovere la cartella della cache trasferibile degli shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Impossibile rimuovere la configurazione personalizzata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Non esiste una configurazione personalizzata per questo gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>La configurazione personalizzata del gioco è stata rimossa con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Impossibile rimuovere la configurazione personalizzata del gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Estrazione RomFS fallita!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>C&apos;è stato un errore nella copia dei file del RomFS o l&apos;operazione è stata annullata dall&apos;utente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Cartelle</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Seleziona la modalità di estrazione della RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Seleziona come vorresti estrarre la RomFS. &lt;br&gt;La modalità Completa copierà tutti i file in una nuova cartella mentre&lt;br&gt;la modalità Cartelle creerà solamente le cartelle e le sottocartelle.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Non c&apos;è abbastanza spazio disponibile nel disco %1 per estrarre la RomFS. Libera lo spazio o seleziona una cartella di estrazione diversa in Emulazione &gt; Configura &gt; Sistema &gt; File system &gt; Cartella di estrazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Estrazione RomFS in corso...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Annulla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Estrazione RomFS riuscita!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>L&apos;operazione è stata completata con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>Impossibile verificare l&apos;integrità dei file.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>I contenuti di questo file non sono stati verificati</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>Verifica integrità fallita.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>I contenuti di questo File potrebbero essere corrotti.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>Verificando l&apos;integrità della ROM...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>Verifica dell&apos;integrità completata con successo!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Crea scorciatoia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Verrà creata una scorciatoia all&apos;AppImage attuale. Potrebbe non funzionare correttamente se effettui un aggiornamento. Vuoi continuare?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Impossibile creare la scorciatoia sul desktop. Il percorso &quot;%1&quot; non esiste.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>Impossibile creare una scorciatoia. Il percorso &quot;%1&quot; non esiste.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Impossibile creare la scorciatoia nel menù delle applicazioni. Il percorso &quot;%1&quot; non esiste e non può essere creato.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Crea icona</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Impossibile creare il file dell&apos;icona. Il percorso &quot;%1&quot; non esiste e non può essere creato.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Avvia %1 con l&apos;emulatore yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Impossibile creare la scorciatoia in %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Scorciatoia creata con successo in %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Impossibile aprire %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Seleziona cartella</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Proprietà</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Non è stato possibile caricare le proprietà del gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Eseguibile Switch (%1);;Tutti i file (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Carica file</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Apri cartella ROM estratta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Cartella selezionata non valida</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>La cartella che hai selezionato non contiene un file &quot;main&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>File installabili Switch (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Installa file</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n file rimanente</numerusform><numerusform>%n file rimanenti</numerusform><numerusform>%n file rimanenti</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installazione del file &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Risultati dell&apos;installazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Per evitare possibli conflitti, sconsigliamo di installare i giochi base su NAND.
Usa questa funzione solo per installare aggiornamenti e DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n nuovo file è stato installato
@@ -4370,7 +4369,7 @@ Usa questa funzione solo per installare aggiornamenti e DLC.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n file è stato sovrascritto
@@ -4379,7 +4378,7 @@ Usa questa funzione solo per installare aggiornamenti e DLC.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n file non è stato installato a causa di errori
@@ -4388,195 +4387,195 @@ Usa questa funzione solo per installare aggiornamenti e DLC.</translation>
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Applicazione di sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Archivio di sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Aggiornamento di un&apos;applicazione di sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Pacchetto firmware (tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Pacchetto firmware (tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Gioco</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Aggiornamento di gioco</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Titolo delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Seleziona il tipo di installazione NCA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Seleziona il tipo del file NCA da installare:
(Nella maggior parte dei casi, il valore predefinito &apos;Gioco&apos; va bene.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Installazione fallita</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Il tipo che hai selezionato per l&apos;NCA non è valido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>File non trovato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>File &quot;%1&quot; non trovato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Requisiti hardware non soddisfatti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Il tuo sistema non soddisfa i requisiti hardware consigliati. La funzionalità di segnalazione della compatibilità è stata disattivata.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Account di yuzu non trovato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Per segnalare la compatibilità di un gioco, devi collegare il tuo account yuzu. &lt;br&gt;&lt;br/&gt;Per collegare il tuo account yuzu, vai su Emulazione &amp;gt;
Configurazione &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Impossibile aprire l&apos;URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Non è stato possibile aprire l&apos;URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Registrazione TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Vuoi sovrascrivere il file del giocatore 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Rilevata configurazione non valida</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Il controller portatile non può essere utilizzato in modalità dock. Verrà selezionato il controller Pro.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>L&apos;Amiibo corrente è stato rimosso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Errore</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Il gioco in uso non è alla ricerca di Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>File Amiibo (%1);; Tutti i file (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Carica Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Impossibile caricare i dati dell&apos;Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Il file selezionato non è un Amiibo valido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Il file selezionato è già in uso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Si è verificato un errore sconosciuto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4585,145 +4584,177 @@ Configurazione &amp;gt; Web.</translation>
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
- <translation type="unfinished"/>
+ <translation>Nessun Firmware disponibile.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>Devi installare il firmware per usare l&apos;applet dell&apos;Album.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>Applet Album</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>L&apos;applet dell&apos;Album non è disponibile. Reinstalla il firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>Devi installare il firmware per usare l&apos;applet Cabinet.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Applet Cabinet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>L&apos;applet del Cabinet non è disponibile. Reinstalla il firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
- <translation type="unfinished"/>
+ <translation>Per usare l&apos;editor dei Mii, devi installare il firmware.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
- <translation type="unfinished"/>
+ <translation>Editor Mii</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
- <translation type="unfinished"/>
+ <translation>L&apos;Editor dei Mii non è disponibile. Reinstalla il firmware.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Cattura screenshot</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Immagine PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Stato TAS: In esecuzione (%1/%2)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Stato TAS: Registrazione in corso (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Stato TAS: In attesa (%1/%2)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Stato TAS: Non valido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Interrompi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Avvia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Interrompi r&amp;egistrazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>R&amp;egistra</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Compilazione di %n shader</numerusform><numerusform>Compilazione di %n shader</numerusform><numerusform>Compilazione di %n shader</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Risoluzione: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Velocità: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Velocità: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Gioco: %1 FPS (Sbloccati)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Gioco: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUME: MUTO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>VOLUME: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Conferma ri-derivazione chiavi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4740,37 +4771,37 @@ Se sei sicuro di voler procedere,
Questa azione eliminerà i tuoi file delle chiavi autogenerati e ripeterà il processo di derivazione delle chiavi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Fusi mancanti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0 mancante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Main mancante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO mancante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Componenti di derivazione mancanti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Chiavi di crittografia mancanti. &lt;br&gt;Segui &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guida introduttiva di yuzu&lt;/a&gt; per ottenere tutte le tue chiavi, il firmware e i giochi.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4779,49 +4810,49 @@ Questa operazione potrebbe durare fino a un minuto in
base alle prestazioni del tuo sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Derivazione chiavi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Decrittazione dell&apos;archivio di sistema fallita</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Le chiavi di crittografia non sono riuscite a decrittare il firmware. &lt;br&gt;Segui &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guida introduttiva di yuzu&lt;/a&gt; per estrarre tutte le tue chiavi, il firmware e i giochi dalla tua Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Seleziona Target dell&apos;Estrazione del RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Seleziona quale RomFS vorresti estrarre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Sei sicuro di voler chiudere yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Sei sicuro di voler arrestare l&apos;emulazione? Tutti i progressi non salvati verranno perduti.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4973,241 +5004,251 @@ Vuoi forzare l&apos;arresto?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Preferito</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Avvia gioco</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Avvia gioco senza la configurazione personalizzata</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Apri la cartella dei dati di salvataggio</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Apri la cartella delle mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Apri la cartella della cache trasferibile delle pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Rimuovi</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Rimuovi l&apos;aggiornamento installato</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Rimuovi tutti i DLC installati</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Rimuovi la configurazione personalizzata</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>Resetta il Tempo di Gioco</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Rimuovi Storage Cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Rimuovi la cache delle pipeline OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Rimuovi la cache delle pipeline Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Rimuovi tutte le cache delle pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Rimuovi tutti i contenuti installati</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Estrai RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Estrai RomFS su SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Verifica Integrità</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Copia il Title ID negli Appunti</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Vai alla pagina di GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Crea scorciatoia</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Aggiungi al desktop</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Aggiungi al menù delle applicazioni</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Proprietà</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Scansiona le sottocartelle</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Rimuovi cartella dei giochi</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Sposta in alto</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Sposta in basso</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Apri cartella</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Cancella</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nome</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Compatibilità</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Add-on</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Tipo di file</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Dimensione</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>Tempo di Gioco</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>In-game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Il gioco parte, ma non può essere completato a causa di arresti anomali o di glitch importanti.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfetto</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Il gioco funziona senza problemi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Giocabile</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Il gioco presenta alcuni glitch audio o video minori ed è possibile giocare dall&apos;inizio alla fine.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Menù</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Il gioco si avvia, ma è impossibile proseguire oltre la schermata iniziale.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Non si avvia</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Il gioco si blocca quando viene avviato.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Non testato</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Il gioco non è ancora stato testato.</translation>
</message>
@@ -5215,7 +5256,7 @@ Vuoi forzare l&apos;arresto?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Clicca due volte per aggiungere una nuova cartella alla lista dei giochi</translation>
</message>
@@ -5228,12 +5269,12 @@ Vuoi forzare l&apos;arresto?</translation>
<translation><numerusform>%1 di %n risultato</numerusform><numerusform>%1 di %n risultati</numerusform><numerusform>%1 di %n risultati</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filtro:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Inserisci pattern per filtrare</translation>
</message>
@@ -5351,6 +5392,7 @@ Messaggio di debug:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Finestra principale</translation>
</message>
@@ -5456,6 +5498,11 @@ Messaggio di debug:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Mostra/nascondi la barra di stato</translation>
</message>
@@ -5694,186 +5741,216 @@ Messaggio di debug:</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Aiuto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Installa file su NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>Carica &amp;file...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Carica &amp;cartella...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>&amp;Esci</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>Arre&amp;sta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Reinizializza chiavi...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>&amp;Verifica i Contenuti Installati</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Informazioni su yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>&amp;Modalità finestra singola</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Configura...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Visualizza le intestazioni del dock dei widget</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Mostra barra del &amp;filtro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Mostra barra di &amp;stato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Mostra barra di stato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Sfoglia lobby di gioco pubblica</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Crea stanza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Esci dalla stanza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>Collegamento &amp;diretto alla stanza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Mostra stanza attuale</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>Schermo intero</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Riavvia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Carica/Rimuovi &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Segnala la compatibilità</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Apri la pagina delle &amp;mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Apri la &amp;guida introduttiva</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;Domande frequenti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Apri la cartella di yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>Cattura schermo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>Apri l&apos;&amp;Album</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>&amp;Imposta Nickname e Proprietario</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>&amp;Rimuovi i Dati di Gioco</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>%Resetta gli Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>&amp;Formatta gli Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
- <translation type="unfinished"/>
+ <translation>Apri l&apos;&amp;Editor dei Mii</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Configura TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Configura il gioco in uso...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Avvia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Reimposta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>R&amp;egistra</translation>
</message>
@@ -6181,27 +6258,27 @@ p, li { white-space: pre-wrap; }
<translation>Non in gioco</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Titoli SD installati</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Titoli NAND installati</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Titoli di sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Aggiungi nuova cartella dei giochi</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Preferiti</translation>
</message>
@@ -6727,7 +6804,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6740,7 +6817,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Due Joycon</translation>
</message>
@@ -6753,7 +6830,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon sinistro</translation>
</message>
@@ -6766,7 +6843,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon destro</translation>
</message>
@@ -6795,7 +6872,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Portatile</translation>
</message>
@@ -6911,32 +6988,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>Non ci sono abbastanza controllers collegati.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Controller GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poké Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Controller NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Controller SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Controller N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/ja_JP.ts b/dist/languages/ja_JP.ts
index 8c06a0afd..6ff603a2d 100644
--- a/dist/languages/ja_JP.ts
+++ b/dist/languages/ja_JP.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>自動 (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>既定 (%1)</translation>
@@ -893,49 +893,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>クラッシュ時にミニダンプを生成</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>これを有効にすると、最新のオーディオコマンドリストがコンソールに出力されます。オーディオレンダラーを使用するゲームにのみ影響します。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>詳細なレポートサービスの有効化**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>** yuzuを終了したときに自動的にリセットされます。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>再起動が必要</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>この設定を適用するには yuzu を再起動する必要があります.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>ウェブアプレットがコンパイルされていません</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation type="unfinished"/>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1354,7 +1334,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>入力された組合せの衝突</translation>
</message>
@@ -1375,27 +1355,37 @@ This would ban both their forum username and their IP address.</source>
<translation>無効</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>デフォルトに戻す</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>消去</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>ボタンが競合しています</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>デフォルトのボタン配列はすでに %1 に割り当てられています。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>デフォルトの組合せはすでに %1 に割り当てられています。</translation>
</message>
@@ -2508,7 +2498,7 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="15"/>
<source>Can be toggled via a hotkey. Default hotkey is Ctrl + F9</source>
- <translation type="unfinished"/>
+ <translation>ホットキーで切り替えできます。 デフォルトのホットキーは Ctrl + F9 です</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_mouse_panning.ui" line="24"/>
@@ -3359,80 +3349,85 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="89"/>
<source>Show Add-Ons Column</source>
- <translation>アドオン列を表示</translation>
+ <translation>アドオンを表示</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="96"/>
<source>Show Size Column</source>
- <translation>サイズ列を表示</translation>
+ <translation>サイズを表示</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="103"/>
<source>Show File Types Column</source>
- <translation>ファイルタイプ列を表示</translation>
+ <translation>ファイルタイプを表示</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>プレイ時間を表示</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>ゲームアイコンサイズ:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>フォルダアイコンサイズ:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>1行目の表示内容:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>2行目の表示内容:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>スクリーンショット</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>スクリーンショット時に保存先を確認する(Windowsのみ)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>スクリーンショットの保存先:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>解像度:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>スクリーンショットの保存先を選択...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3750,965 +3745,1003 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>yuzuの改善に役立てるため、&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;匿名データが収集されます&lt;/a&gt;。&lt;br/&gt;&lt;br/&gt;統計情報を共有しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>テレメトリ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>壊れたVulkanのインストールが検出されました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>起動時にVulkanの初期化に失敗しました。&lt;br&gt;&lt;br&gt;この問題を解決するための手順は&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;こちら&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Webアプレットをロード中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Webアプレットの無効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Webアプレットを無効にすると、未定義の動作になる可能性があるため、スーパーマリオ3Dオールスターズでのみ使用するようにしてください。本当にWebアプレットを無効化しますか?
(デバッグ設定で再度有効にすることができます)。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>ビルド中のシェーダー数</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>現在選択されている解像度の倍率。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>現在のエミュレーション速度。値が100%より高いか低い場合、エミュレーション速度がSwitchより速いか遅いことを示します。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>ゲームが現在表示している1秒あたりのフレーム数。これはゲームごと、シーンごとに異なります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Switchフレームをエミュレートするのにかかる時間で、フレームリミットやV-Syncは含まれません。フルスピードエミュレーションの場合、最大で16.67ミリ秒になります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>消音解除</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>消音</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>音量をリセット</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>最近のファイルをクリア(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>再開(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>中断(&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>古いゲームフォーマットの警告</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>このゲームでは、分解されたROMディレクトリフォーマットを使用しています。これは、NCA、NAX、XCI、またはNSPなどに取って代わられた古いフォーマットです。分解されたROMディレクトリには、アイコン、メタデータ、およびアップデートサポートがありません。&lt;br&gt;&lt;br&gt;yuzuがサポートするSwitchフォーマットの説明については、&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;wikiをチェックしてください&lt;/a&gt;。このメッセージは二度と表示されません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>ROMロード中にエラーが発生しました!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>このROMフォーマットはサポートされていません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>ビデオコア初期化中にエラーが発生しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzuは、ビデオコアの実行中にエラーが発生しました。これは通常、内蔵GPUも含め、古いGPUドライバが原因です。詳しくはログをご覧ください。ログへのアクセス方法については、以下のページをご覧ください:&lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;ログファイルのアップロード方法について&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROMのロード中にエラー! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzuクイックスタートガイド&lt;/a&gt;を参照してファイルを再ダンプしてください。&lt;br&gt;またはyuzu wiki及び&lt;/a&gt;yuzu Discord&lt;/a&gt;を参照するとよいでしょう。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>不明なエラーが発生しました。詳細はログを確認して下さい。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>ソフトウェアを終了中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>データのセーブ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Modデータ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>”%1”フォルダを開けませんでした</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>フォルダが存在しません!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>シェーダーキャッシュを開けませんでした</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>このタイトル用のシェーダーキャッシュディレクトリの作成に失敗しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>コンテンツの削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>アップデートの削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>DLC の削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>インストールされたゲームのコンテンツを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>インストールされたゲームのアップデートを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>インストールされたゲームの DLC を削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>エントリ削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>削除しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>インストールされたゲームを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>ゲームはNANDにインストールされていないため、削除できません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>インストールされたアップデートを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>このタイトルのアップデートはインストールされていません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>このタイトルにはDLCがインストールされていません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1にインストールされたDLCを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
- <translation>転送可能なOpenGLシェーダーキャッシュを削除しますか?</translation>
+ <translation>OpenGLシェーダーキャッシュを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
- <translation>転送可能なVulkanシェーダーキャッシュを削除しますか?</translation>
+ <translation>Vulkanシェーダーキャッシュを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
- <translation>転送可能なすべてのシェーダーキャッシュを削除しますか?</translation>
+ <translation>すべてのシェーダーキャッシュを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>このタイトルのカスタム設定を削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>キャッシュストレージを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>ファイル削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>プレイ時間情報を削除</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>プレイ時間をリセットしますか?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
- <translation>転送可能なシェーダーキャッシュの削除エラー</translation>
+ <translation>シェーダーキャッシュの削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>このタイトル用のシェーダーキャッシュは存在しません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
- <translation>転送可能なシェーダーキャッシュが正常に削除されました。</translation>
+ <translation>シェーダーキャッシュを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
- <translation>転送可能なシェーダーキャッシュを削除できませんでした。</translation>
+ <translation>シェーダーキャッシュの削除に失敗しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
- <translation>転送可能なシェーダーキャッシュの削除エラー</translation>
+ <translation>シェーダーキャッシュの削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
- <translation>転送可能なシェーダーキャッシュを正常に削除しました。</translation>
+ <translation>シェーダーキャッシュを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
- <translation>転送可能なシェーダーキャッシュディレクトリの削除に失敗しました。</translation>
+ <translation>シェーダーキャッシュディレクトリの削除に失敗しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>カスタム設定の削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>このタイトルのカスタム設定は存在しません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>カスタム設定を正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>カスタム設定の削除に失敗しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFSの抽出に失敗しました!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>RomFSファイルをコピー中にエラーが発生したか、ユーザー操作によりキャンセルされました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>フル</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>スケルトン</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFSダンプモードの選択</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>RomFSのダンプ方法を選択してください。&lt;br&gt;”完全”はすべてのファイルが新しいディレクトリにコピーされます。&lt;br&gt;”スケルトン”はディレクトリ構造を作成するだけです。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 に RomFS を展開するための十分な空き領域がありません。Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root で、空き容量を確保するか、別のダンプディレクトリを選択してください。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>RomFSを抽出中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>キャンセル</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS抽出成功!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>操作は成功しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
- <translation type="unfinished"/>
+ <translation>整合性の確認を実行できませんでした!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
- <translation type="unfinished"/>
+ <translation>ファイルの妥当性は確認されませんでした.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
- <translation type="unfinished"/>
+ <translation>整合性の確認に失敗しました!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
- <translation type="unfinished"/>
+ <translation>ファイルが破損しているかもしれません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
- <translation type="unfinished"/>
+ <translation>整合性を確認中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
- <translation type="unfinished"/>
+ <translation>整合性の確認に成功しました!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>ショートカットを作成</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>アイコンを作成</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
- <translation type="unfinished"/>
+ <translation>%1 へのショートカット作成に失敗しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
- <translation type="unfinished"/>
+ <translation>%1 へのショートカット作成に成功しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>”%1”を開けませんでした</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>ディレクトリの選択</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>プロパティ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>ゲームプロパティをロード出来ませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch実行ファイル (%1);;すべてのファイル (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>ファイルのロード</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>展開されているROMディレクトリを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>無効なディレクトリが選択されました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>選択されたディレクトリに”main”ファイルが見つかりませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>インストール可能なスイッチファイル (*.nca *.nsp *.xci);;任天堂コンテンツアーカイブ (*.nca);;任天堂サブミッションパッケージ (*.nsp);;NXカートリッジイメージ (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>ファイルのインストール</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>残り %n ファイル</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>&quot;%1&quot;ファイルをインストールしています・・・</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>インストール結果</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>競合を避けるため、NANDにゲーム本体をインストールすることはお勧めしません。
この機能は、アップデートやDLCのインストールにのみ使用してください。</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n ファイルが新たにインストールされました
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n ファイルが上書きされました
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n ファイルのインストールに失敗しました
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>システムアプリケーション</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>システムアーカイブ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>システムアプリケーションアップデート</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>ファームウェアパッケージ(Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>ファームウェアパッケージ(Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>ゲーム</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>ゲームアップデート</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>ゲームDLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>差分タイトル</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>NCAインストール種別を選択・・・</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>インストールするNCAタイトル種別を選択して下さい:
(ほとんどの場合、デフォルトの”ゲーム”で問題ありません。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>インストール失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>選択されたNCAのタイトル種別が無効です。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>ファイルが存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>ファイル”%1”が存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>yuzuアカウントが存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>ゲームの互換性テストケースを送信するには、yuzuアカウントをリンクする必要があります。&lt;br&gt;&lt;br/&gt;yuzuアカウントをリンクするには、エミュレーション > 設定 > Web から行います。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>URLオープンエラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL&quot;%1&quot;を開けません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation> TAS 記録中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>プレイヤー1のファイルを上書きしますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>無効な設定を検出しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>携帯コントローラはドックモードで使用できないため、Proコントローラが選択されます。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>現在の amiibo は削除されました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>現在のゲームはamiiboを要求しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>amiiboファイル (%1);;すべてのファイル (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>amiiboのロード</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>amiiboデータ読み込み中にエラーが発生しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
- <translation type="unfinished"/>
+ <translation>選択されたファイルは有効な amiibo ではありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
- <translation type="unfinished"/>
+ <translation>選択されたファイルはすでに使用中です</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>不明なエラーが発生しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
- <translation type="unfinished"/>
+ <translation>以下のファイルの確認に失敗しました:
+
+%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
+ <translation>ファームウェアがありません</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>スクリーンショットのキャプチャ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG画像 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 状態: 実行中 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS 状態: 記録中 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 状態: アイドル %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS 状態: 無効</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>実行停止(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>実行(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>記録停止(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>記録(&amp;R)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>構築中: %n 個のシェーダー</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>拡大率: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>速度:%1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>速度:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Game: %1 FPS(制限解除)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>ゲーム:%1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>フレーム:%1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>音量: ミュート</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>音量: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>キーの再取得確認</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4725,37 +4758,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
実行すると、自動生成された鍵ファイルが削除され、鍵生成モジュールが再実行されます。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>ヒューズがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0がありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Mainがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - PRODINFOがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>派生コンポーネントがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>暗号化キーがありません。&lt;br&gt;キー、ファームウェア、ゲームを取得するには&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu クイックスタートガイド&lt;/a&gt;を参照ください。&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4764,49 +4797,49 @@ on your system&apos;s performance.</source>
1分以上かかります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>派生キー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>システムアーカイブの復号に失敗しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>RomFSダンプターゲットの選択</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>ダンプしたいRomFSを選択して下さい。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>yuzuを終了しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>エミュレーションを停止しますか?セーブされていない進行状況は失われます。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4958,241 +4991,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>お気に入り</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>ゲームを開始</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>カスタム設定なしでゲームを開始</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>セーブデータディレクトリを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Modデータディレクトリを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
- <translation>転送可能なパイプラインキャッシュを開く</translation>
+ <translation>パイプラインキャッシュを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>インストールされているアップデートを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>全てのインストールされているDLCを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>カスタム設定を削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>プレイ時間情報を削除</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>キャッシュストレージを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>OpenGLパイプラインキャッシュを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Vulkanパイプラインキャッシュを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>すべてのパイプラインキャッシュを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>全てのインストールされているコンテンツを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>RomFSをダンプ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>RomFSをSDMCにダンプ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
- <translation type="unfinished"/>
+ <translation>整合性を確認</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>タイトルIDをクリップボードへコピー</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>GameDBエントリを表示</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>ショートカットを作成</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>デスクトップに追加</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>アプリケーションメニューに追加</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>プロパティ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>サブフォルダをスキャンする</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>ゲームディレクトリを削除する</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ 上へ移動</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ 下へ移動</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>ディレクトリの場所を開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>クリア</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>ゲーム名</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>互換性</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>アドオン</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>ファイル種別</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>ファイルサイズ</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>プレイ時間</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>カンペキ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>プレイ可</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>イントロ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>起動不可</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>ゲームは起動時にクラッシュしました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>未テスト</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>このゲームはまだテストされていません。</translation>
</message>
@@ -5200,7 +5243,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>新しいゲームリストフォルダを追加するにはダブルクリックしてください。</translation>
</message>
@@ -5213,12 +5256,12 @@ Would you like to bypass this and exit anyway?</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>フィルター:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>フィルターパターンを入力</translation>
</message>
@@ -5302,7 +5345,7 @@ Would you like to bypass this and exit anyway?</source>
<location filename="../../src/yuzu/multiplayer/host_room.cpp" line="186"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
- <translation>公開ロビーへの部屋のアナウンスに失敗しました。部屋を公開するためには、Emulation -&gt; Configure -&gt; Web で有効なyuzuアカウントが設定されている必要があります。もし、部屋を公開ロビーに公開したくないのであれば、代わりに非公開を選択してください。
+ <translation>公開ロビーへのルームのアナウンスに失敗しました。ルームを公開するためには、エミュレーション -&gt; 設定 -&gt; Web で有効なyuzuアカウントが設定されている必要があります。もし、ルームを公開ロビーに公開したくないのであれば、代わりに非公開を選択してください。
デバッグメッセージ :</translation>
</message>
</context>
@@ -5336,6 +5379,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>メイン画面</translation>
</message>
@@ -5441,6 +5485,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>ステータスバー切り替え</translation>
</message>
@@ -5679,186 +5728,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>ヘルプ(&amp;H)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>ファイルをNANDにインストール...(&amp;I)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>ファイルをロード...(&amp;L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>フォルダをロード...(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>終了(&amp;E)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>中断(&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>停止(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>鍵を再初期化...(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>インストールされたコンテンツを確認(&amp;V)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>yuzuについて(&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>シングルウィンドウモード(&amp;W)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>設定...(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>ドックウィジェットヘッダ(&amp;O)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>フィルタバー(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>ステータスバー(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>ステータスバーの表示</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>公開ゲームロビーを参照 (&amp;B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>ルームを作成 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>ルームを退出 (&amp;L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>ルームに直接接続 (&amp;D)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>現在のルームを表示 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>全画面表示(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>再実行(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>&amp;Amiibo をロード/削除...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>互換性を報告(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>&amp;Modページを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>クイックスタートガイドを開く(&amp;Q)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>&amp;yuzuフォルダを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>スクリーンショットをキャプチャ(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
- <source>Open &amp;Mii Editor</source>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>ゲームデータを削除(&amp;D)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
+ <source>Open &amp;Mii Editor</source>
+ <translation>&amp;Mii エディタを開く</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>TASを設定... (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>現在のゲームを設定...(&amp;U)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>実行(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>リセット(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>記録(&amp;R)</translation>
</message>
@@ -5930,7 +6009,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="117"/>
<source>Not Connected. Click here to find a room!</source>
- <translation>接続されていません。ここをクリックして部屋を見つけてください。</translation>
+ <translation>接続されていません。ここをクリックしてルームを見つけてください。</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
@@ -6015,7 +6094,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
<source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
- <translation>この部屋のホストはあなたを入室禁止にしています。ホストと話をしてアクセス禁止を解除してもらうか、他の部屋を試してみてください。</translation>
+ <translation>このルームのホストはあなたを入室禁止にしています。ホストと話をしてアクセス禁止を解除してもらうか、他のルームを試してみてください。</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
@@ -6035,7 +6114,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
<source>Connection to room lost. Try to reconnect.</source>
- <translation>部屋への接続が失われました。再接続を試みてください。</translation>
+ <translation>ルームへの接続が失われました。再接続を試みてください。</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
@@ -6085,7 +6164,7 @@ Proceed anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
- <translation>部屋を閉じようとしています。ネットワーク接続がすべて終了します。</translation>
+ <translation>ルームを閉じようとしています。ネットワーク接続がすべて終了します。</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
@@ -6095,7 +6174,7 @@ Proceed anyway?</source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
- <translation>部屋を退出しようとしています。ネットワーク接続はすべて終了します。</translation>
+ <translation>ルームを退出しようとしています。ネットワーク接続はすべて終了します。</translation>
</message>
</context>
<context>
@@ -6165,27 +6244,27 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>インストール済みSDタイトル</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>インストール済みNANDタイトル</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>システムタイトル</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>新しいゲームディレクトリを追加する</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>お気に入り</translation>
</message>
@@ -6711,7 +6790,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Proコントローラ</translation>
</message>
@@ -6724,7 +6803,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Joy-Con(L/R)</translation>
</message>
@@ -6737,7 +6816,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joy-Con(L)</translation>
</message>
@@ -6750,7 +6829,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joy-Con(R)</translation>
</message>
@@ -6779,7 +6858,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>携帯モード</translation>
</message>
@@ -6895,32 +6974,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>ゲームキューブコントローラ</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>モンスターボールプラス</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>ファミコン・コントローラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>スーパーファミコン・コントローラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>ニンテンドウ64・コントローラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>メガドライブ</translation>
</message>
@@ -7026,7 +7110,7 @@ Please try again or contact the developer of the software.</source>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="213"/>
<source>Change settings for which user?</source>
- <translation type="unfinished"/>
+ <translation>どのユーザの設定を変更しますか?</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="216"/>
@@ -7036,12 +7120,12 @@ Please try again or contact the developer of the software.</source>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="219"/>
<source>Which user will be transferred to another console?</source>
- <translation type="unfinished"/>
+ <translation>どのユーザを別のコンソールに転送しますか?</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="222"/>
<source>Send save data for which user?</source>
- <translation type="unfinished"/>
+ <translation>どのユーザにセーブデータを送信しますか?</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="226"/>
@@ -7107,7 +7191,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="158"/>
<source>[%1] %2</source>
- <translation type="unfinished"/>
+ <translation>[%1] %2</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="184"/>
diff --git a/dist/languages/ko_KR.ts b/dist/languages/ko_KR.ts
index f5204f1aa..0dc3cd319 100644
--- a/dist/languages/ko_KR.ts
+++ b/dist/languages/ko_KR.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>자동 (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>기본 (%1)</translation>
@@ -894,49 +894,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>충돌후 미니덤프 생성</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>이 옵션을 활성화하면 가장 최근에 생성된 오디오 명령어 목록을 콘솔에 출력할 수 있습니다. 오디오 렌더러를 사용하는 게임에만 영향을 줍니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>콘솔에 오디오 명령어 덤프</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>자세한 리포팅 서비스 활성화**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Yuzu가 종료되면 자동으로 재설정됩니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>재시작 필요</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>이 설정을 적용하려면 yuzu를 다시 시작해야 합니다.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>웹 애플릿이 컴파일되지 않음</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>MiniDump 생성이 컴파일되지 않음</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1355,7 +1335,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>키 시퀀스 충돌</translation>
</message>
@@ -1376,27 +1356,37 @@ This would ban both their forum username and their IP address.</source>
<translation>유효하지않음</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>초기화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>비우기</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>키 시퀀스 충돌</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>기본 키 시퀀스가 %1에 이미 할당되었습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>기본 키 시퀀스가 %1에 이미 할당되었습니다.</translation>
</message>
@@ -3373,67 +3363,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>파일 형식 열 표시</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>게임 아이콘 크기:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>폴더 아이콘 크기:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>1번째 행 텍스트:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>2번째 행 텍스트:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>스크린샷</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>스크린샷 저장 위치 물어보기 (Windows 전용)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>스크린샷 경로 :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>해상도:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>스크린샷 경로 선택...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>자동 (%1 x %2, %3 x %4)</translation>
@@ -3751,965 +3746,1001 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>yuzu를 개선하기 위해 &lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;익명 데이터가 수집됩니다.&lt;/a&gt; &lt;br/&gt;&lt;br/&gt;사용 데이터를 공유하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>원격 측정</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>깨진 Vulkan 설치 감지됨</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>부팅하는 동안 Vulkan 초기화에 실패했습니다.&lt;br&gt;&lt;br&gt;문제 해결 지침을 보려면 &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;여기&lt;/a&gt;를 클릭하세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>게임 실행중</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>웹 애플릿을 로드하는 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>웹 애플릿 비활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>웹 애플릿을 비활성화하면 정의되지 않은 동작이 발생할 수 있으며 Super Mario 3D All-Stars에서만 사용해야 합니다. 웹 애플릿을 비활성화하시겠습니까?
(디버그 설정에서 다시 활성화할 수 있습니다.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>현재 생성중인 셰이더의 양</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>현재 선택된 해상도 배율입니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>현재 에뮬레이션 속도. 100%보다 높거나 낮은 값은 에뮬레이션이 Switch보다 빠르거나 느린 것을 나타냅니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>게임이 현재 표시하고 있는 초당 프레임 수입니다. 이것은 게임마다 다르고 장면마다 다릅니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>프레임 제한이나 수직 동기화를 계산하지 않고 Switch 프레임을 에뮬레이션 하는 데 걸린 시간. 최대 속도로 에뮬레이트 중일 때에는 대부분 16.67 ms 근처입니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>음소거 해제</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>음소거</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>볼륨 재설정</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>Clear Recent Files(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>에뮬레이트 마우스 사용</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>실제 마우스 입력과 마우스 패닝은 호환되지 않습니다. 마우스 패닝을 허용하려면 입력 고급 설정에서 에뮬레이트 마우스를 비활성화하세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>재개(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>일시중지(&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>오래된 게임 포맷 경고</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>이 게임 파일은 &apos;분해된 ROM 디렉토리&apos;라는 오래된 포맷을 사용하고 있습니다. 해당 포맷은 NCA, NAX, XCI 또는 NSP와 같은 다른 포맷으로 대체되었으며 분해된 ROM 디렉토리에는 아이콘, 메타 데이터 및 업데이트가 지원되지 않습니다.&lt;br&gt;&lt;br&gt;yuzu가 지원하는 다양한 Switch 포맷에 대한 설명은 &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;위키를 확인하세요.&lt;/a&gt; 이 메시지는 다시 표시되지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>ROM 로드 중 오류 발생!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>지원되지 않는 롬 포맷입니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>비디오 코어를 초기화하는 동안 오류가 발생했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>비디오 코어를 실행하는 동안 yuzu에 오류가 발생했습니다. 이것은 일반적으로 통합 드라이버를 포함하여 오래된 GPU 드라이버로 인해 발생합니다. 자세한 내용은 로그를 참조하십시오. 로그 액세스에 대한 자세한 내용은 &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;로그 파일 업로드 방법&lt;/a&gt; 페이지를 참조하세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROM 불러오는 중 오류 발생! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;파일들을 다시 덤프하기 위해&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 빠른 시작 가이드&lt;/a&gt; 를 따라주세요.&lt;br&gt;도움이 필요할 시 yuzu 위키&lt;/a&gt; 를 참고하거나 yuzu 디스코드&lt;/a&gt; 를 이용해보세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>알 수 없는 오류가 발생했습니다. 자세한 내용은 로그를 참고하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64비트)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32비트)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>소프트웨어를 닫는 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>세이브 데이터</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>모드 데이터</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>%1 폴더 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>폴더가 존재하지 않습니다!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>전송 가능한 셰이더 캐시 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>이 타이틀에 대한 셰이더 캐시 디렉토리를 생성하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>콘텐츠 제거 중 오류 발생</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>업데이트 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>DLC 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>설치된 게임 콘텐츠를 제거하겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>설치된 게임 업데이트를 제거하겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>설치된 게임 DLC를 제거하겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>항목 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>삭제 완료</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>설치된 기본 게임을 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>기본 게임은 NAND에 설치되어 있지 않으며 제거 할 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>설치된 업데이트를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>이 타이틀에 대해 설치된 업데이트가 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>이 타이틀에 설치된 DLC가 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>설치된 %1 DLC를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>OpenGL 전송 가능한 셰이더 캐시를 삭제하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Vulkan 전송 가능한 셰이더 캐시를 삭제하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>모든 전송 가능한 셰이더 캐시를 삭제하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>사용자 지정 게임 구성을 제거 하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>캐시 저장소를 제거하겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>파일 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>전송 가능한 셰이더 캐시 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>이 타이틀에 대한 셰이더 캐시가 존재하지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>전송 가능한 셰이더 캐시를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>전송 가능한 셰이더 캐시를 제거하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Vulkan 드라이버 파이프라인 캐시 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>드라이버 파이프라인 캐시를 제거하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>전송 가능한 셰이더 캐시 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>전송 가능한 셰이더 캐시를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>전송 가능한 셰이더 캐시 디렉토리를 제거하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>사용자 지정 구성 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>이 타이틀에 대한 사용자 지정 구성이 존재하지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>사용자 지정 게임 구성을 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>사용자 지정 게임 구성을 제거하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS 추출 실패!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>RomFS 파일을 복사하는 중에 오류가 발생했거나 사용자가 작업을 취소했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>전체</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>뼈대</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFS 덤프 모드 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>RomFS 덤프 방법을 선택하십시오.&lt;br&gt;전체는 모든 파일을 새 디렉토리에 복사하고&lt;br&gt;뼈대는 디렉토리 구조 만 생성합니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1에 RomFS를 추출하기에 충분한 여유 공간이 없습니다. 공간을 확보하거나 에뮬레이견 &gt; 설정 &gt; 시스템 &gt; 파일시스템 &gt; 덤프 경로에서 다른 덤프 디렉토리를 선택하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>RomFS 추출 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>취소</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS 추출이 성공했습니다!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>작업이 성공적으로 완료되었습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>바로가기 만들기</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>현재 AppImage에 대한 바로 가기가 생성됩니다. 업데이트하면 제대로 작동하지 않을 수 있습니다. 계속합니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>바탕 화면에 바로가기를 만들 수 없습니다. 경로 &quot;%1&quot;이(가) 존재하지 않습니다.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>애플리케이션 메뉴에서 바로가기를 만들 수 없습니다. 경로 &quot;%1&quot;이(가) 존재하지 않으며 생성할 수 없습니다.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>아이콘 만들기</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>아이콘 파일을 만들 수 없습니다. 경로 &quot;%1&quot;이(가) 존재하지 않으며 생성할 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>yuzu 에뮬레이터로 %1 시작</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>%1에서 바로가기를 만들기 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>%1 바로가기를 성공적으로 만듬</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>%1 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>경로 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>속성</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>게임 속성을 로드 할 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch 실행파일 (%1);;모든 파일 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>파일 로드</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>추출된 ROM 디렉토리 열기</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>잘못된 디렉토리 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>선택한 디렉토리에 &apos;main&apos;파일이 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>설치 가능한 Switch 파일 (*.nca *.nsp *.xci);;Nintendo 컨텐츠 아카이브 (*.nca);;Nintendo 서브미션 패키지 (*.nsp);;NX 카트리지 이미지 (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>파일 설치</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n개의 파일이 남음</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>파일 &quot;%1&quot; 설치 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>설치 결과</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>충돌을 피하기 위해, 낸드에 베이스 게임을 설치하는 것을 권장하지 않습니다.
이 기능은 업데이트나 DLC를 설치할 때에만 사용해주세요.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n개의 파일이 새로 설치되었습니다.
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n개의 파일을 덮어썼습니다.
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n개의 파일을 설치하지 못했습니다.
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>시스템 애플리케이션</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>시스템 아카이브</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>시스템 애플리케이션 업데이트</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>펌웨어 패키지 (A타입)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>펌웨어 패키지 (B타입)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>게임</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>게임 업데이트</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>게임 DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>델타 타이틀</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>NCA 설치 유형 선택...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>이 NCA를 설치할 타이틀 유형을 선택하세요:
(대부분의 경우 기본값인 &apos;게임&apos;이 괜찮습니다.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>설치 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>NCA 타이틀 유형이 유효하지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>파일을 찾을 수 없음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>파일 &quot;%1&quot;을 찾을 수 없습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>하드웨어 요구 사항이 충족되지 않음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>시스템이 권장 하드웨어 요구 사항을 충족하지 않습니다. 호환성 보고가 비활성화되었습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>yuzu 계정 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>게임 호환성 테스트 결과를 제출하려면 yuzu 계정을 연결해야합니다.&lt;br&gt;&lt;br/&gt;yuzu 계정을 연결하려면 에뮬레이션 &amp;gt; 설정 &amp;gt; 웹으로 가세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>URL 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL &quot;%1&quot;을 열 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS 레코딩</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>플레이어 1의 파일을 덮어쓰시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>유효하지 않은 설정 감지</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>휴대 모드용 컨트롤러는 거치 모드에서 사용할 수 없습니다. 프로 컨트롤러로 대신 선택됩니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>현재 amiibo가 제거되었습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>현재 게임은 amiibo를 찾고 있지 않습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo 파일 (%1);; 모든 파일 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Amiibo 로드</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Amiibo 데이터 로드 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>선택한 파일은 유효한 amiibo가 아닙니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>선택한 파일은 이미 사용 중입니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>알수없는 오류가 발생했습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>스크린샷 캡처</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG 이미지 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 상태: %1/%2 실행 중</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS 상태: 레코딩 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 상태: 유휴 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS 상태: 유효하지 않음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>실행 중지(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>시작(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>레코딩 중지(&amp;e)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>레코드(&amp;R)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>빌드중: %n개 셰이더</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>스케일: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>속도: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>속도: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>게임: %1 FPS (제한없음)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>게임: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>프레임: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>AA 없음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>볼륨: 음소거</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>볼륨: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>키 재생성 확인</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4726,37 +4757,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
자동 생성되었던 키 파일들이 삭제되고 키 생성 모듈이 다시 실행됩니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>fuses 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Main 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - PRODINFO 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>파생 구성 요소 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>암호화 키가 없습니다. &lt;br&gt;모든 키, 펌웨어 및 게임을 얻으려면 &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 빠른 시작 가이드&lt;/a&gt;를 따르세요.&lt;br&gt;&lt;br&gt; &lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4765,49 +4796,49 @@ on your system&apos;s performance.</source>
소요될 수 있습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>파생 키</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>시스템 아카이브 암호 해독 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>암호화 키가 펌웨어를 해독하지 못했습니다. &lt;br&gt; 암호화 키와 펌웨어 및 게임을 얻기위해&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt; Yuzu 빠른 시작 가이드 &lt;/a&gt;를 따르세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>RomFS 덤프 대상 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>덤프할 RomFS를 선택하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>yuzu를 닫으시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>에뮬레이션을 중지하시겠습니까? 모든 저장되지 않은 진행 상황은 사라집니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4959,241 +4990,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>선호하는 게임</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>게임 시작</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>맞춤 설정 없이 게임 시작</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>세이브 데이터 경로 열기</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>MOD 데이터 경로 열기</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>전송 가능한 파이프라인 캐시 열기</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>설치된 업데이트 삭제</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>설치된 모든 DLC 삭제</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>사용자 지정 구성 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>캐시 스토리지 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>OpenGL 파이프라인 캐시 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Vulkan 파이프라인 캐시 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>모든 파이프라인 캐시 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>설치된 모든 컨텐츠 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>RomFS를 덤프</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>RomFS를 SDMC로 덤프</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>클립보드에 타이틀 ID 복사</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>GameDB 항목으로 이동</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>바로가기 만들기</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>데스크톱에 추가</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>애플리케이션 메뉴에 추가</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>속성</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>하위 폴더 스캔</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>게임 디렉토리 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ 위로 이동</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ 아래로 이동</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>디렉토리 위치 열기</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>초기화</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>이름</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>호환성</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>부가 기능</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>파일 형식</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>크기</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>게임 내</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>게임이 시작되지만, 충돌이나 주요 결함으로 인해 게임이 완료되지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>완벽함</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>문제 없이 게임 플레이가 가능합니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>재생 가능</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>약간의 그래픽 또는 오디오 결함이 있는 게임 기능이 있으며 처음부터 끝까지 플레이할 수 있습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>인트로/메뉴</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>게임이 로드되지만 시작 화면을 지나서 진행할 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>실행 불가</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>게임 실행 시 크래시가 일어납니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>테스트되지 않음</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>이 게임은 아직 테스트되지 않았습니다.</translation>
</message>
@@ -5201,7 +5242,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>더블 클릭하여 게임 목록에 새 폴더 추가</translation>
</message>
@@ -5214,12 +5255,12 @@ Would you like to bypass this and exit anyway?</source>
<translation><numerusform>%1 중의 %n 결과</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>필터:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>검색 필터 입력</translation>
</message>
@@ -5337,6 +5378,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>메인 윈도우</translation>
</message>
@@ -5442,6 +5484,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>상태 표시줄 전환</translation>
</message>
@@ -5680,186 +5727,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>TAS(&amp;T)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>도움말(&amp;H)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>낸드에 파일 설치(&amp;I)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>파일 불러오기...(&amp;L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>폴더 불러오기...(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>종료(&amp;X)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>일시중지(&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>정지(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>키 재설정...(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>yuzu 정보(&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>싱글 창 모드(&amp;W)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>설정(&amp;f)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>독 위젯 헤더 표시(&amp;o)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>필터링 바 표시(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>상태 표시줄 보이기(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>상태 표시줄 보이기</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>공개 게임 로비 찾아보기(&amp;B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>방 만들기(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>방에서 나가기(&amp;L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>방에 직접 연결(&amp;D)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>현재 방 표시(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>전체 화면(&amp;u)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>재시작(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Amiibo 로드/제거(&amp;A)...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>호환성 보고(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>게임 모드 페이지 열기(&amp;M)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>빠른 시작 가이드 열기(&amp;Q)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>FAQ(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>yuzu 폴더 열기(&amp;y)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>스크린샷 찍기(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>TAS설정...(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>실행중인 게임 맞춤 설정...(&amp;u)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>시작(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>리셋(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>레코드(&amp;e)</translation>
</message>
@@ -6167,27 +6244,27 @@ p, li { white-space: pre-wrap; }
<translation>게임을 하지 않음</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>설치된 SD 타이틀</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>설치된 NAND 타이틀</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>시스템 타이틀</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>새 게임 디렉토리 추가</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>선호하는 게임</translation>
</message>
@@ -6713,7 +6790,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>프로 컨트롤러</translation>
</message>
@@ -6726,7 +6803,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>듀얼 조이콘</translation>
</message>
@@ -6739,7 +6816,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>왼쪽 조이콘</translation>
</message>
@@ -6752,7 +6829,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>오른쪽 조이콘</translation>
</message>
@@ -6781,7 +6858,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>휴대 모드</translation>
</message>
@@ -6897,32 +6974,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>몬스터볼 Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>세가 제네시스</translation>
</message>
diff --git a/dist/languages/nb.ts b/dist/languages/nb.ts
index d5e1ea138..14be337d6 100644
--- a/dist/languages/nb.ts
+++ b/dist/languages/nb.ts
@@ -373,13 +373,13 @@ Dette vil bannlyse både deres forum brukernavn og deres IP adresse.</translatio
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Auto (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Normalverdi (%1)</translation>
@@ -893,49 +893,29 @@ Dette vil bannlyse både deres forum brukernavn og deres IP adresse.</translatio
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Lag Minidump Etter Kræsj</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Aktiver dette for å sende den siste genererte lydkommandolisten til konsollen. Påvirker bare spill som bruker lydrenderen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Dump Lydkommandoer Til Konsollen**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Aktiver Verbose Reporting Services**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Dette blir automatisk tilbakestilt når yuzu lukkes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Omstart Nødvendig</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu må startes på nytt for å bruke denne innstillingen.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Web-applet ikke kompilert</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>MiniDump-opprettelse ikke kompilert</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1354,7 +1334,7 @@ Dette vil bannlyse både deres forum brukernavn og deres IP adresse.</translatio
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Mostridende tastesekvens</translation>
</message>
@@ -1375,27 +1355,37 @@ Dette vil bannlyse både deres forum brukernavn og deres IP adresse.</translatio
<translation>Ugyldig</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Gjenopprett Standardverdi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Fjern</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Motstridende knappesekvens</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Standardknappesekvensen er allerede tildelt til: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Standardtastesekvensen er allerede tildelt til: %1</translation>
</message>
@@ -3373,67 +3363,72 @@ Dra punkter for å endre posisjon, eller dobbelttrykk på tabellfelter for å re
<translation>Vis Kolonne For Filtype</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Spillikonstørrelse:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Mappeikonstørrelse:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Rad 1 Tekst:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Rad 2 Tekst:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Skjermbilder</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Spør om hvor skjermbilder skal lagres (kun for Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Skjermbildebane:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>TextLabel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Oppløsning:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Velg Skermbildebane...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Auto (%1 x %2, %3 x %4)</translation>
@@ -3751,612 +3746,616 @@ Dra punkter for å endre posisjon, eller dobbelttrykk på tabellfelter for å re
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonym data blir samlet inn&lt;/a&gt;for å hjelpe til med å forbedre yuzu.&lt;br/&gt;&lt;br/&gt;Vil du dele din bruksdata med oss?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Ødelagt Vulkan-installasjon oppdaget</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Vulkan-initialisering mislyktes under oppstart.&lt;br&gt;&lt;br&gt;Klikk&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;her for instruksjoner for å løse problemet&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Kjører et spill</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Laster web-applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Slå av web-applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Deaktivering av webappleten kan føre til udefinert oppførsel og bør bare brukes med Super Mario 3D All-Stars. Er du sikker på at du vil deaktivere webappleten?
(Dette kan aktiveres på nytt i feilsøkingsinnstillingene).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Antall shader-e som bygges for øyeblikket</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Den valgte oppløsningsskaleringsfaktoren.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Nåværende emuleringshastighet. Verdier høyere eller lavere en 100% indikerer at emuleringen kjører raskere eller tregere enn en Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Hvor mange bilder per sekund spiller viser. Dette vil variere fra spill til spill og scene til scene.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tid det tar for å emulere et Switch bilde. Teller ikke med bildebegrensing eller v-sync. For full-hastighet emulering burde dette være 16.67 ms. på det høyeste.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Slå på lyden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Lydløs</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Tilbakestill volum</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Tøm Nylige Filer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Emulert mus er aktivert</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Ekte museinndata og musepanning er inkompatible. Deaktiver den emulerte musen i avanserte innstillinger for inndata for å tillate musepanning.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Fortsett</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Paus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Advarsel: Utdatert Spillformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Du bruker en dekonstruert ROM-mappe for dette spillet, som er et utdatert format som har blitt erstattet av andre formater som NCA, NAX, XCI, eller NSP. Dekonstruerte ROM-mapper mangler ikoner, metadata, og oppdateringsstøtte.&lt;br&gt;&lt;br&gt;For en forklaring på diverse Switch-formater som yuzu støtter,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;sjekk vår wiki&lt;/a&gt;. Denne meldingen vil ikke bli vist igjen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Feil under innlasting av ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Dette ROM-formatet er ikke støttet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>En feil oppstod under initialisering av videokjernen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu har oppdaget en feil under kjøring av videokjernen. Dette er vanligvis forårsaket av utdaterte GPU-drivere, inkludert for integrert grafikk. Vennligst sjekk loggen for flere detaljer. For mer informasjon om å finne loggen, besøk følgende side: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Uploadd the Log File&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Feil under lasting av ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Vennligst følg &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;hurtigstartsguiden&lt;/a&gt; for å redumpe filene dine. &lt;br&gt;Du kan henvise til yuzu wikien&lt;/a&gt; eller yuzu Discorden&lt;/a&gt; for hjelp.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>En ukjent feil oppstod. Se loggen for flere detaljer.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Lukker programvare...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Lagre Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Feil Under Åpning av %1 Mappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Mappen eksisterer ikke!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Feil ved åpning av overførbar shaderbuffer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Kunne ikke opprette shader cache-katalogen for denne tittelen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Feil ved fjerning av innhold</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Feil ved fjerning av oppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Feil ved fjerning av DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Fjern Innstallert Spillinnhold?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Fjern Installert Spilloppdatering?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Fjern Installert Spill DLC?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Fjern oppføring</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Fjerning lykkes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Vellykket fjerning av det installerte basisspillet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Grunnspillet er ikke installert i NAND og kan ikke bli fjernet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Fjernet vellykket den installerte oppdateringen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Det er ingen oppdatering installert for denne tittelen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Det er ingen DLC installert for denne tittelen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Fjernet vellykket %1 installerte DLC-er.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Slette OpenGL Overførbar Shaderbuffer?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Slette Vulkan Overførbar Shaderbuffer?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Slette Alle Overførbare Shaderbuffere?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Fjern Tilpasset Spillkonfigurasjon?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Fjerne Hurtiglagringen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Fjern Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Feil under fjerning av overførbar shader cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>En shaderbuffer for denne tittelen eksisterer ikke.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Lykkes i å fjerne den overførbare shader cachen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Feil under fjerning av den overførbare shader cachen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Feil ved fjerning av Vulkan Driver-Rørledningsbuffer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Kunne ikke fjerne driverens rørledningsbuffer.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Feil ved fjerning av overførbare shaderbuffere</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Vellykket fjerning av overførbare shaderbuffere.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Feil ved fjerning av overførbar shaderbuffer katalog.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Feil Under Fjerning Av Tilpasset Konfigurasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>En tilpasset konfigurasjon for denne tittelen finnes ikke.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Fjernet vellykket den tilpassede spillkonfigurasjonen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Feil under fjerning av den tilpassede spillkonfigurasjonen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Utvinning av RomFS Feilet!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Det oppstod en feil under kopiering av RomFS filene eller så kansellerte brukeren operasjonen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Fullstendig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Skjelett</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Velg RomFS Dump Modus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Velg hvordan du vil dumpe RomFS.&lt;br&gt;Fullstendig vil kopiere alle filene til en ny mappe mens &lt;br&gt;skjelett vil bare skape mappestrukturen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Det er ikke nok ledig plass på %1 til å pakke ut RomFS. Vennligst frigjør plass eller velg en annen dump-katalog under Emulering &gt; Konfigurer &gt; System &gt; Filsystem &gt; Dump Root.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Utvinner RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS Utpakking lyktes!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Operasjonen fullført vellykket.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>Integritetsverifisering kunne ikke utføres!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>Filinnholdet ble ikke kontrollert for gyldighet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>Integritetsverifisering mislyktes!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>Filinnholdet kan være skadet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>Verifiserer integritet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>Integritetsverifisering vellykket!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Lag Snarvei</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Dette vil opprette en snarvei til gjeldende AppImage. Dette fungerer kanskje ikke bra hvis du oppdaterer. Fortsette?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Kan ikke opprette snarvei på skrivebordet. Stien &quot;%1&quot; finnes ikke.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Kan ikke opprette snarvei i applikasjonsmenyen. Stien &quot;%1&quot; finnes ikke og kan ikke opprettes.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Lag Ikon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Kan ikke opprette ikonfil. Stien &quot;%1&quot; finnes ikke og kan ikke opprettes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Start %1 med yuzu-emulatoren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Mislyktes i å opprette en snarvei ved %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Opprettet en snarvei til %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Feil ved åpning av %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Velg Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Egenskaper</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Spillets egenskaper kunne ikke bli lastet inn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Kjørbar Fil (%1);;Alle Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Last inn Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Åpne Utpakket ROM Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Ugyldig Mappe Valgt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Mappen du valgte inneholder ikke en &apos;main&apos; fil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Installerbar Switch-Fil (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xcI)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Installer Filer</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n fil gjenstår</numerusform><numerusform>%n filer gjenstår</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installerer fil &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Insallasjonsresultater</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>For å unngå mulige konflikter fraråder vi brukere å installere basisspill på NAND.
Bruk kun denne funksjonen til å installere oppdateringer og DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n fil ble nylig installert
@@ -4364,7 +4363,7 @@ Bruk kun denne funksjonen til å installere oppdateringer og DLC.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n fil ble overskrevet
@@ -4372,7 +4371,7 @@ Bruk kun denne funksjonen til å installere oppdateringer og DLC.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n fil ble ikke installert
@@ -4380,194 +4379,194 @@ Bruk kun denne funksjonen til å installere oppdateringer og DLC.</translation>
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Systemapplikasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Systemarkiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Systemapplikasjonsoppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Firmware Pakke (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Firmware-Pakke (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Spill</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Spilloppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Spill tilleggspakke</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta Tittel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Velg NCA Installasjonstype...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vennligst velg typen tittel du vil installere denne NCA-en som:
(I de fleste tilfellene, standarden &apos;Spill&apos; fungerer.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Feil under Installasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Titteltypen du valgte for NCA-en er ugyldig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Fil ikke funnet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Filen &quot;%1&quot; ikke funnet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Krav til maskinvare ikke oppfylt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Systemet ditt oppfyller ikke de anbefalte maskinvarekravene. Kompatibilitetsrapportering er deaktivert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Mangler yuzu Bruker</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>For å sende inn et testtilfelle for spillkompatibilitet, må du linke yuzu-brukeren din.&lt;br&gt;&lt;br/&gt;For å linke yuzu-brukeren din, gå til Emulasjon &amp;gt; Konfigurasjon &amp;gt; Nett.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Feil under åpning av URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Kunne ikke åpne URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS-innspilling</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Overskriv filen til spiller 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Ugyldig konfigurasjon oppdaget</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Håndholdt kontroller kan ikke brukes i dokket modus. Pro-kontroller vil bli valgt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Den valgte amiibo-en har blitt fjernet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Feil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Det kjørende spillet sjekker ikke for amiibo-er</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo-Fil (%1);; Alle Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Last inn Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Feil ved lasting av Amiibo data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Den valgte filen er ikke en gyldig amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Den valgte filen er allerede i bruk</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>En ukjent feil oppso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4576,145 +4575,177 @@ Bruk kun denne funksjonen til å installere oppdateringer og DLC.</translation>
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Ta Skjermbilde</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG Bilde (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS-tilstand: Kjører %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS-tilstand: Spiller inn %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS-tilstand: Venter %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS-tilstand: Ugyldig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Stopp kjøring</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Stopp innspilling (&amp;E)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>Spill inn (%E)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Bygger: %n shader</numerusform><numerusform>Bygger: %n shader-e</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Hastighet: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Hastighet: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Spill: %1 FPS (ubegrenset)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Spill: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Ramme: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>INGEN AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUM: DEMPET</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>VOLUM: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Bekreft Nøkkel-Redirevasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4731,37 +4762,37 @@ og eventuelt lag backups.
Dette vil slette dine autogenererte nøkkel-filer og kjøre nøkkel-derivasjonsmodulen på nytt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Mangler fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Mangler BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Mangler BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- Mangler PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Derivasjonskomponenter Mangler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Krypteringsnøkler mangler. &lt;br&gt;Vennligst følg &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzus oppstartsguide&lt;/a&gt; for å få alle nøklene, fastvaren og spillene dine.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4770,49 +4801,49 @@ Dette kan ta opp til et minutt avhengig
av systemytelsen din.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Deriverer Nøkler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Dekryptering av systemarkiv mislyktes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Krypteringsnøkler klarte ikke å dekryptere firmware. &lt;br&gt;Vennligst følg &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;quickstartguiden for yuzu &lt;/a&gt; for å få alle nøkler, firmware og spill.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Velg RomFS Dump-Mål</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vennligst velg hvilken RomFS du vil dumpe.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Er du sikker på at du vil lukke yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Er du sikker på at du vil stoppe emulasjonen? All ulagret fremgang vil bli tapt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4964,241 +4995,251 @@ Vil du overstyre dette og lukke likevel?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Legg til som favoritt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Start Spill</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Star Spill Uten Tilpasset Konfigurasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Åpne Lagret Data plassering</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Åpne Mod Data plassering</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Åpne Overførbar Rørledningsbuffer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Fjern</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Fjern Installert Oppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Fjern All Installert DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Fjern Tilpasset Konfigurasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Fjern Hurtiglagring</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Fjer OpenGL Rørledningsbuffer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Fjern Vulkan Rørledningsbuffer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Fjern Alle Rørledningsbuffere</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Fjern All Installert Innhold</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Dump RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Dump RomFS til SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Verifiser integritet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Kopier Tittel-ID til Utklippstavle</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Naviger til GameDB-oppføring</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>lag Snarvei</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Legg Til På Skrivebordet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Legg Til Applikasjonsmenyen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Egenskaper</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Skann Undermapper</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Fjern Spillmappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Flytt Opp</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Flytt Ned</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Åpne Spillmappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Fjern</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Navn</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatibilitet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Tilleggsprogrammer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Fil Type</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Størrelse</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>i Spillet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Spillet starter, men krasjer eller større feil gjør at det ikke kan fullføres.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Spillet kan spilles uten problemer.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Spillbart</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Spillet fungerer med mindre grafiske eller lydfeil og kan spilles fra start til slutt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Meny</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Spillet lastes inn, men kan ikke gå videre forbi startskjermen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Vil ikke starte</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Spillet krasjer under oppstart.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Ikke testet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Spillet har ikke blitt testet ennå.</translation>
</message>
@@ -5206,7 +5247,7 @@ Vil du overstyre dette og lukke likevel?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Dobbeltrykk for å legge til en ny mappe i spillisten</translation>
</message>
@@ -5219,12 +5260,12 @@ Vil du overstyre dette og lukke likevel?</translation>
<translation><numerusform>%1 of %n resultat</numerusform><numerusform>%1 of %n resultater</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filter:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Angi mønster for å filtrere</translation>
</message>
@@ -5342,6 +5383,7 @@ Feilmelding:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Hovedvindu</translation>
</message>
@@ -5447,6 +5489,11 @@ Feilmelding:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Veksle Statuslinje</translation>
</message>
@@ -5685,186 +5732,216 @@ Feilmelding:</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Hjelp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Installer filer til NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>Last inn fil... (&amp;O)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Last inn mappe (&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>&amp;Avslutt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Paus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Stop</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Reinitialiser nøkler...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>Om yuzu (&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Énvindusmodus (&amp;W)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Kon&amp;figurer...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Vis Overskrifter for Dock Widget (&amp;O)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Vis &amp;filterlinje</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Vis &amp;statuslinje</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Vis statuslinje</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>Bla gjennom den offentlige spillobbyen (&amp;B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>Opprett Rom (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>Forlat Rommet (&amp;L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>Direkte Tilkobling Til Rommet (&amp;D)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>Vis nåværende rom (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>F&amp;ullskjerm</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>Omstart (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Last/Fjern Amiibo (&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>Rapporter kompatibilitet (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Åpne Modifikasjonssiden (&amp;M)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Åpne Hurtigstartsguiden (&amp;Q)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Åpne &amp;yuzu Mappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>Ta Skjermbilde (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>Konfigurer TAS (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Konfigurer Gjeldende Spill (&amp;U)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>Tilbakestill (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>Spill inn (%E)</translation>
</message>
@@ -6172,27 +6249,27 @@ p, li { white-space: pre-wrap; }
<translation>Spiller ikke et spill</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Installerte SD-titler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Installerte NAND-titler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>System Titler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Legg til ny spillmappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoritter</translation>
</message>
@@ -6718,7 +6795,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro-Kontroller</translation>
</message>
@@ -6731,7 +6808,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Doble Joycons</translation>
</message>
@@ -6744,7 +6821,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Venstre Joycon</translation>
</message>
@@ -6757,7 +6834,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Høyre Joycon</translation>
</message>
@@ -6786,7 +6863,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Håndholdt</translation>
</message>
@@ -6902,32 +6979,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/nl.ts b/dist/languages/nl.ts
index ec7577c9d..c1d9985d9 100644
--- a/dist/languages/nl.ts
+++ b/dist/languages/nl.ts
@@ -373,13 +373,13 @@ Dit zou zowel hun forum gebruikersnaam als hun IP-adres verbannen.</translation>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Auto (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Standaard (%1)</translation>
@@ -881,49 +881,29 @@ Dit zou zowel hun forum gebruikersnaam als hun IP-adres verbannen.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Maak Minidump na Crash</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Zet dit aan om de laatst gegenereerde audio commandolijst naar de console te sturen. Alleen van invloed op spellen die de audio renderer gebruiken.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Dump Audio-opdrachten naar Console**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Schakel Verbose Reporting Services** in</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Deze optie wordt automatisch gereset wanneer yuzu is gesloten.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Herstart Vereist</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu moet opnieuw opstarten om deze instelling toe te passen.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Webapplet niet gecompileerd</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>MiniDump-creatie niet gecompileerd</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1342,7 +1322,7 @@ Dit zou zowel hun forum gebruikersnaam als hun IP-adres verbannen.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Ongeldige Toetsvolgorde</translation>
</message>
@@ -1363,27 +1343,37 @@ Dit zou zowel hun forum gebruikersnaam als hun IP-adres verbannen.</translation>
<translation>Ongeldig</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Standaard Herstellen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Wis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Conflicterende Knoppencombinatie</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>De standaard knoppencombinatie is al toegewezen aan: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>De ingevoerde toetsencombinatie is al in gebruik door: %1</translation>
</message>
@@ -3361,67 +3351,72 @@ Versleep punten om de positie te veranderen, of dubbelklik op tabelcellen om waa
<translation>Toon Kolom Bestandstypen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Grootte Spelicoon:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Grootte Mapicoon:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Rij 1 Tekst:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Rij 2 Tekst:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Schermafbeelding</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Vraag waar schermafbeeldingen moeten worden opgeslagen (alleen Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Schermafbeeldingspad:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>TextLabel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Resolutie:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Selecteer Schermafbeeldingspad...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Auto (%1 x %2, %3 x %4)</translation>
@@ -3739,612 +3734,616 @@ Versleep punten om de positie te veranderen, of dubbelklik op tabelcellen om waa
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Annonieme gegevens worden verzameld&lt;/a&gt; om yuzu te helpen verbeteren. &lt;br/&gt;&lt;br/&gt; Zou je jouw gebruiksgegevens met ons willen delen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetrie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Beschadigde Vulkan-installatie gedetecteerd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Vulkan-initialisatie mislukt tijdens het opstarten.&lt;br&gt;&lt;br&gt;Klik &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;hier voor instructies om het probleem op te lossen&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Een spel uitvoeren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Web Applet Laden...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Schakel Webapplet uit</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Het uitschakelen van de webapplet kan leiden tot ongedefinieerd gedrag en mag alleen gebruikt worden met Super Mario 3D All-Stars. Weet je zeker dat je de webapplet wilt uitschakelen?
(Deze kan opnieuw worden ingeschakeld in de Debug-instellingen).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Het aantal shaders dat momenteel wordt gebouwd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>De huidige geselecteerde resolutieschaalmultiplier.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Huidige emulatiesnelheid. Waarden hoger of lager dan 100% geven aan dat de emulatie sneller of langzamer werkt dan een Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Hoeveel beelden per seconde het spel momenteel weergeeft. Dit varieert van spel tot spel en van scène tot scène.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tijd die nodig is om een Switch-beeld te emuleren, beeldbeperking of v-sync niet meegerekend. Voor emulatie op volle snelheid mag dit maximaal 16,67 ms zijn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Dempen opheffen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Dempen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Herstel Volume</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Wis Recente Bestanden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Geëmuleerde muis is ingeschakeld</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Echte muisinvoer en muispanning zijn niet compatibel. Schakel de geëmuleerde muis uit in de geavanceerde invoerinstellingen om muispanning mogelijk te maken.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Doorgaan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Onderbreken</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Waarschuwing Verouderd Spelformaat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Je gebruikt het gedeconstrueerde ROM-mapformaat voor dit spel, wat een verouderd formaat is dat vervangen is door andere zoals NCA, NAX, XCI, of NSP. Deconstructed ROM-mappen missen iconen, metadata, en update-ondersteuning.&lt;br&gt;&lt;br&gt;Voor een uitleg van de verschillende Switch-formaten die yuzu ondersteunt,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt; bekijk onze wiki&lt;/a&gt;. Dit bericht wordt niet meer getoond.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Fout tijdens het laden van een ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Het ROM-formaat wordt niet ondersteund.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Er is een fout opgetreden tijdens het initialiseren van de videokern.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu is een fout tegengekomen tijdens het uitvoeren van de videokern. Dit wordt meestal veroorzaakt door verouderde GPU-drivers, inclusief geïntegreerde. Zie het logboek voor meer details. Voor meer informatie over toegang tot het log, zie de volgende pagina: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Hoe upload je het logbestand&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Fout tijdens het laden van ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Volg de &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu snelstartgids&lt;/a&gt; om je bestanden te redumpen.&lt;br&gt;Je kunt de yuzu-wiki&lt;/a&gt;of de yuzu-Discord&lt;/a&gt; raadplegen voor hulp.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Een onbekende fout heeft plaatsgevonden. Kijk in de log voor meer details.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Software sluiten...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Save Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Fout tijdens het openen van %1 map</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Map bestaat niet!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Fout bij het openen van overdraagbare shader-cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Kon de shader-cache-map voor dit spel niet aanmaken.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Fout bij het verwijderen van de inhoud</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Fout bij het verwijderen van de update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Fout bij het verwijderen van DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Geïnstalleerde Spelinhoud Verwijderen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Geïnstalleerde Spel-update Verwijderen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Geïnstalleerde Spel-DLC Verwijderen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Verwijder Invoer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Met Succes Verwijderd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Het geïnstalleerde basisspel is succesvol verwijderd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Het basisspel is niet geïnstalleerd in de NAND en kan niet worden verwijderd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>De geïnstalleerde update is succesvol verwijderd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Er is geen update geïnstalleerd voor dit spel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Er is geen DLC geïnstalleerd voor dit spel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 geïnstalleerde DLC met succes verwijderd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Overdraagbare OpenGL-shader-cache Verwijderen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Overdraagbare Vulkan-shader-cache Verwijderen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Alle Overdraagbare Shader-caches Verwijderen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Aangepaste Spelconfiguratie Verwijderen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Verwijder Cache-opslag?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Verwijder Bestand</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Fout bij het verwijderen van Overdraagbare Shader-cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Er bestaat geen shader-cache voor dit spel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>De overdraagbare shader-cache is verwijderd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Kon de overdraagbare shader-cache niet verwijderen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Fout bij het verwijderen van Pijplijn-cache van Vulkan-driver</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Kon de pijplijn-cache van de driver niet verwijderen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Fout bij het verwijderen van overdraagbare shader-caches</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>De overdraagbare shader-caches zijn verwijderd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Kon de overdraagbare shader-cache-map niet verwijderen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Fout bij het verwijderen van aangepaste configuratie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Er bestaat geen aangepaste configuratie voor dit spel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>De aangepaste spelconfiguratie is verwijderd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Kon de aangepaste spelconfiguratie niet verwijderen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS-extractie Mislukt!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Er is een fout opgetreden bij het kopiëren van de RomFS-bestanden of de gebruiker heeft de bewerking geannuleerd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Volledig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Skelet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Selecteer RomFS-dumpmodus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Selecteer hoe je de RomFS gedumpt wilt hebben.&lt;br&gt;Volledig zal alle bestanden naar de nieuwe map kopiëren, terwijl &lt;br&gt;Skelet alleen de mapstructuur zal aanmaken.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Er is niet genoeg vrije ruimte op %1 om de RomFS uit te pakken. Maak ruimte vrij of kies een andere dumpmap bij Emulatie &gt; Configuratie &gt; Systeem &gt; Bestandssysteem &gt; Dump Root.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>RomFS uitpakken...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Annuleren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS-extractie Geslaagd!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>De bewerking is succesvol voltooid.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>Integriteitsverificatie kon niet worden uitgevoerd!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>De inhoud van bestanden werd niet gecontroleerd op geldigheid.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>Integriteitsverificatie mislukt!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>Bestandsinhoud kan corrupt zijn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>Integriteit verifiëren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>Integriteitsverificatie geslaagd!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Maak Snelkoppeling</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Dit maakt een snelkoppeling naar de huidige AppImage. Dit werkt mogelijk niet goed als je een update uitvoert. Doorgaan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Kan geen snelkoppeling op het bureaublad maken. Pad &quot;%1&quot; bestaat niet.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Kan geen snelkoppeling maken in toepassingen menu. Pad &quot;%1&quot; bestaat niet en kan niet worden aangemaakt.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Maak Icoon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Kan geen icoonbestand maken. Pad &quot;%1&quot; bestaat niet en kan niet worden aangemaakt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Voer %1 uiit met de yuzu-emulator</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Er is geen snelkoppeling gemaakt op %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Succesvol een snelkoppeling naar %1 gemaakt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Fout bij openen %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Selecteer Map</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Eigenschappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>De speleigenschappen kunnen niet geladen worden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Executable (%1);;Alle Bestanden (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Laad Bestand</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Open Uitgepakte ROM-map</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Ongeldige Map Geselecteerd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>De map die je hebt geselecteerd bevat geen &apos;main&apos;-bestand.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Installeerbaar Switch-bestand (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Installeer Bestanden</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n bestand(en) resterend</numerusform><numerusform>%n bestand(en) resterend</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Bestand &quot;%1&quot; Installeren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Installeerresultaten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Om mogelijke conflicten te voorkomen, raden we gebruikers af om basisgames te installeren op de NAND.
Gebruik deze functie alleen om updates en DLC te installeren.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n bestand(en) zijn recent geïnstalleerd
@@ -4352,7 +4351,7 @@ Gebruik deze functie alleen om updates en DLC te installeren.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n bestand(en) werden overschreven
@@ -4360,7 +4359,7 @@ Gebruik deze functie alleen om updates en DLC te installeren.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n bestand(en) niet geïnstalleerd
@@ -4368,194 +4367,194 @@ Gebruik deze functie alleen om updates en DLC te installeren.</translation>
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Systeemapplicatie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Systeemarchief</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Systeemapplicatie-update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Filmware-pakket (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Filmware-pakket (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Spel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Spelupdate</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Spel-DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Selecteer NCA-installatiesoort...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Selecteer het type titel waarin je deze NCA wilt installeren:
(In de meeste gevallen is de standaard &quot;Spel&quot; prima).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Installatie Mislukt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Het soort title dat je hebt geselecteerd voor de NCA is ongeldig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Bestand niet gevonden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Bestand &quot;%1&quot; niet gevonden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Er is niet voldaan aan de hardwarevereisten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Je systeem voldoet niet aan de aanbevolen hardwarevereisten. Compatibiliteitsrapportage is uitgeschakeld.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>yuzu-account Ontbreekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Om een spelcompatibiliteitstest in te dienen, moet je je yuzu-account koppelen.&lt;br&gt;&lt;br/&gt;Om je yuzu-account te koppelen, ga naar Emulatie &amp;gt; Configuratie &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Fout bij het openen van URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Kan de URL &quot;%1&quot; niet openen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS-opname</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Het bestand van speler 1 overschrijven?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Ongeldige configuratie gedetecteerd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Handheld-controller kan niet gebruikt worden in docked-modus. Pro controller wordt geselecteerd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>De huidige amiibo is verwijderd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Fout</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Het huidige spel is niet op zoek naar amiibo&apos;s</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo-bestand (%1);; Alle Bestanden (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Laad Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Fout tijdens het laden van de Amiibo-gegevens</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Het geselecteerde bestand is geen geldige amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Het geselecteerde bestand is al in gebruik</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Er is een onbekende fout opgetreden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4564,145 +4563,177 @@ Gebruik deze functie alleen om updates en DLC te installeren.</translation>
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Leg Schermafbeelding Vast</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG-afbeelding (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS-status: %1/%2 In werking</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS-status: %1 Aan het opnemen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS-status: %1/%2 Inactief</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS-status: Ongeldig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Stop Uitvoering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Stop Opname</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>Opnemen</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Bouwen: %n shader(s)</numerusform><numerusform>Bouwen: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Schaal: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Snelheid: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Snelheid: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Spel: %1 FPS (Ontgrendeld)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Game: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>GEEN AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUME: GEDEMPT</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>VOLUME: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Bevestig Sleutelherhaling</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4719,37 +4750,37 @@ en maak eventueel back-ups.
Dit zal je automatisch gegenereerde sleutelbestanden verwijderen en de sleutelafleidingsmodule opnieuw uitvoeren.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Missing fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0 Ontbreekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Main Ontbreekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - PRODINFO Ontbreekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Afleidingscomponenten ontbreken</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Encryptiesleutels ontbreken. &lt;br&gt;Volg &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;de yuzu-snelstartgids&lt;/a&gt; om al je sleutels, firmware en spellen te krijgen.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4758,49 +4789,49 @@ Dit kan tot een minuut duren,
afhankelijk van de prestaties van je systeem.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Sleutels Afleiden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Decryptie van Systeemarchief Mislukt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Encryptiesleutels zijn mislukt om firmware te decoderen. &lt;br&gt;Volg &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;de yuzu-snelstartgids&lt;/a&gt; om al je sleutels, firmware en games te krijgen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Selecteer RomFS-dumpdoel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Selecteer welke RomFS je zou willen dumpen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Weet je zeker dat je yuzu wilt sluiten?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Weet je zeker dat je de emulatie wilt stoppen? Alle niet opgeslagen voortgang zal verloren gaan.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4952,241 +4983,251 @@ Wil je toch afsluiten?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Favoriet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Start Spel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Start Spel zonder Aangepaste Configuratie</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Open Locatie van Save-data</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Open Locatie van Mod-data</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Open Overdraagbare Pijplijn-cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Verwijder</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Verwijder Geïnstalleerde Update</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Verwijder Alle Geïnstalleerde DLC&apos;s</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Verwijder Aangepaste Configuraties</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Verwijder Cache-opslag</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Verwijder OpenGL-pijplijn-cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Verwijder Vulkan-pijplijn-cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Verwijder Alle Pijplijn-caches</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Verwijder Alle Geïnstalleerde Inhoud</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Dump RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Dump RomFS naar SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Verifieer Integriteit</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Kopiëer Titel-ID naar Klembord</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Navigeer naar GameDB-invoer</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Maak Snelkoppeling</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Toevoegen aan Bureaublad</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Toevoegen aan menu Toepassingen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Eigenschappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Scan Submappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Verwijder Spelmap</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Omhoog</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Omlaag</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Open Maplocatie</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Verwijder</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Naam</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Compatibiliteit</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Add-ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Bestandssoort</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Grootte</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>In het spel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Het spel start, maar crashes of grote glitches voorkomen dat het wordt voltooid.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfect</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Het spel kan zonder problemen gespeeld worden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Speelbaar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Het spel werkt met kleine grafische of audiofouten en is speelbaar van begin tot eind.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Het spel wordt geladen, maar komt niet verder dan het startscherm.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Start niet op</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Het spel loopt vast bij het opstarten.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Niet Getest</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Het spel is nog niet getest.</translation>
</message>
@@ -5194,7 +5235,7 @@ Wil je toch afsluiten?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Dubbel-klik om een ​​nieuwe map toe te voegen aan de spellijst</translation>
</message>
@@ -5207,12 +5248,12 @@ Wil je toch afsluiten?</translation>
<translation><numerusform>%1 van %n resultaat(en)</numerusform><numerusform>%1 van %n resultaat(en)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filter:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Voer patroon in om te filteren</translation>
</message>
@@ -5330,6 +5371,7 @@ Debug-bericht: </translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Hoofdvenster</translation>
</message>
@@ -5435,6 +5477,11 @@ Debug-bericht: </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Schakel Statusbalk</translation>
</message>
@@ -5673,186 +5720,216 @@ Debug-bericht: </translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Help</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Installeer Bestanden naar NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>L&amp;aad Bestand...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Laad &amp;Map...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>A&amp;fsluiten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Onderbreken</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Stop</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Herinitialiseer toetsen...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Over yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Modus Enkel Venster</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Con&amp;figureer...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Toon Dock Widget Kopteksten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Toon &amp;Filterbalk</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Toon &amp;Statusbalk</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Toon Statusbalk</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Bladeren door Openbare Spellobby</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Maak Kamer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Verlaat Kamer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Directe Verbinding met Kamer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Toon Huidige Kamer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>Volledig Scherm</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Herstart</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Laad/Verwijder &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Rapporteer Compatibiliteit</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Open &amp;Mod-pagina</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Open &amp;Snelstartgids</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Open &amp;yuzu-map</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Leg Schermafbeelding Vast</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Configureer TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Configureer Huidig Spel...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Herstel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>Opnemen</translation>
</message>
@@ -6160,27 +6237,27 @@ p, li { white-space: pre-wrap; }
<translation>Geen spel aan het spelen</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Geïnstalleerde SD-titels</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Geïnstalleerde NAND-titels</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Systeemtitels</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Voeg Nieuwe Spelmap Toe</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favorieten</translation>
</message>
@@ -6706,7 +6783,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6719,7 +6796,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Twee Joycons</translation>
</message>
@@ -6732,7 +6809,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Linker Joycon</translation>
</message>
@@ -6745,7 +6822,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Rechter Joycon</translation>
</message>
@@ -6774,7 +6851,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
@@ -6890,32 +6967,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube-controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES-controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES-controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64-controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/pl.ts b/dist/languages/pl.ts
index 4fa59f40b..f15091bf4 100644
--- a/dist/languages/pl.ts
+++ b/dist/languages/pl.ts
@@ -373,13 +373,13 @@ To zbanuje jego/jej nick na forum, oraz jego/jej adres IP.</translation>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -891,49 +891,29 @@ Gdy ta opcja jest włączona, niedopasowanie jest uruchamiane tylko wtedy, gdy d
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Utwórz mini zrzut po awarii</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Włącz tę opcję, aby wyświetlić ostatnio wygenerowaną listę poleceń dźwiękowych na konsoli. Wpływa tylko na gry korzystające z renderera dźwięku.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Zrzuć polecenia audio do konsoli**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Włącz Pełne Usługi Raportowania**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**To zresetuje się automatycznie po wyłączeniu yuzu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Ponowne uruchomienie jest wymagane</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu wymaga ponownego uruchomienia w przypadku zastosowania tego ustawienia.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Aplet sieciowy nie został skompilowany</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Tworzenie mini zrzutów nie zostało skompilowane</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1352,7 +1332,7 @@ Gdy ta opcja jest włączona, niedopasowanie jest uruchamiane tylko wtedy, gdy d
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Sprzeczna sekwencja klawiszy</translation>
</message>
@@ -1373,27 +1353,37 @@ Gdy ta opcja jest włączona, niedopasowanie jest uruchamiane tylko wtedy, gdy d
<translation>Nieprawidłowe</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Przywróć ustawienia domyślne</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Wyczyść</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Sprzeczna Sekwencja Przycisków</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Domyślna sekwencja przycisków już jest przypisana do: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Domyślna sekwencja klawiszy jest już przypisana do: %1</translation>
</message>
@@ -3370,67 +3360,72 @@ Przeciągnij punkty, aby zmienić pozycję, lub kliknij dwukrotnie komórki tabe
<translation>Pokaż kolumnę typów plików</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Rozmiar Ikony Gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Rozmiar Ikony Folderu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Tekst 1. linii</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Tekst 2. linii</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Zrzuty ekranu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Pytaj gdzie zapisać zrzuty ekranu (Tylko dla Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Ścieżka zrzutów ekranu:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Rozdzielczość:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Wybierz ścieżkę zrzutów ekranu...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3748,613 +3743,617 @@ Przeciągnij punkty, aby zmienić pozycję, lub kliknij dwukrotnie komórki tabe
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dane anonimowe są gromadzone&lt;/a&gt; aby ulepszyć yuzu. &lt;br/&gt;&lt;br/&gt;Czy chcesz udostępnić nam swoje dane o użytkowaniu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Wykryto uszkodzoną instalację Vulkana</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Inicjalizacja Vulkana nie powiodła się podczas uruchamiania.&lt;br&gt;&lt;br&gt;Kliknij&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;tutaj aby uzyskać instrukcje dotyczące rozwiązania tego problemu&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Ładowanie apletu internetowego...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Wyłącz Aplet internetowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Wyłączanie web appletu może doprowadzić do nieokreślonych zachowań - wyłączyć applet należy jedynie grając w Super Mario 3D All-Stars. Na pewno chcesz wyłączyć web applet?
(Można go ponownie włączyć w ustawieniach debug.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Ilość budowanych shaderów</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Obecnie wybrany mnożnik rozdzielczości.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Aktualna prędkość emulacji. Wartości większe lub niższe niż 100% wskazują, że emulacja działa szybciej lub wolniej niż Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Ile klatek na sekundę gra aktualnie wyświetla. To będzie się różnić w zależności od gry, od sceny do sceny.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Czas potrzebny do emulacji klatki na sekundę Switcha, nie licząc ograniczania klatek ani v-sync. Dla emulacji pełnej szybkości powinno to wynosić co najwyżej 16,67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Usuń Ostatnie pliki</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Emulacja myszki jest aktywna</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Kontynuuj</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pauza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>OSTRZEŻENIE! Nieaktualny format gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Używasz zdekonstruowanego formatu katalogu ROM dla tej gry, który jest przestarzałym formatem, który został zastąpiony przez inne, takie jak NCA, NAX, XCI lub NSP. W zdekonstruowanych katalogach ROM brakuje ikon, metadanych i obsługi aktualizacji.&lt;br&gt;&lt;br&gt; Aby znaleźć wyjaśnienie różnych formatów Switch obsługiwanych przez yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt; sprawdź nasze wiki&lt;/a&gt;. Ta wiadomość nie pojawi się ponownie.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Błąd podczas wczytywania ROMu!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Ten format ROMu nie jest wspierany.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Wystąpił błąd podczas inicjowania rdzenia wideo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu napotkał błąd podczas uruchamiania rdzenia wideo. Jest to zwykle spowodowane przestarzałymi sterownikami GPU, w tym zintegrowanymi. Więcej szczegółów znajdziesz w pliku log. Więcej informacji na temat dostępu do log-u można znaleźć na następującej stronie: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Jak przesłać plik log&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Błąd podczas wczytywania ROMu! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Postępuj zgodnie z&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu quickstart guide&lt;/a&gt; aby zrzucić ponownie swoje pliki.&lt;br&gt;Możesz odwołać się do wiki yuzu&lt;/a&gt;lub discord yuzu &lt;/a&gt; po pomoc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Wystąpił nieznany błąd. Więcej informacji można znaleźć w pliku log.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Zamykanie aplikacji...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Zapis danych</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Dane modów</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Błąd podczas otwarcia folderu %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Folder nie istnieje!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Błąd podczas otwierania przenośnej pamięci podręcznej Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Nie udało się stworzyć ścieżki shaderów dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Błąd podczas usuwania zawartości</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Błąd podczas usuwania aktualizacji</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Błąd podczas usuwania dodatków</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Czy usunąć zainstalowaną zawartość gry?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Czy usunąć zainstalowaną aktualizację gry?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Czy usunąć zainstalowane dodatki gry?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Usuń wpis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Pomyślnie usunięto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Pomyślnie usunięto zainstalowaną grę.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Gra nie jest zainstalowana w NAND i nie może zostać usunięta.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Pomyślnie usunięto zainstalowaną łatkę.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Brak zainstalowanych łatek dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Brak zainstalowanych DLC dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Pomyślnie usunięto %1 zainstalowane DLC.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Usunąć Transferowalne Shadery OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Usunąć Transferowalne Shadery Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Usunąć Wszystkie Transferowalne Shadery?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Usunąć niestandardową konfigurację gry?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Usunąć pamięć podręczną?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Usuń plik</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Błąd podczas usuwania przenośnej pamięci podręcznej Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Pamięć podręczna Shaderów dla tego tytułu nie istnieje.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Pomyślnie usunięto przenośną pamięć podręczną Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Nie udało się usunąć przenośnej pamięci Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Błąd podczas usuwania pamięci podręcznej strumienia sterownika Vulkana</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Błąd podczas usuwania pamięci podręcznej strumienia sterownika.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Błąd podczas usuwania Transferowalnych Shaderów</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Pomyślnie usunięto transferowalne shadery.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Nie udało się usunąć ścieżki transferowalnych shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Błąd podczas usuwania niestandardowej konfiguracji</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Niestandardowa konfiguracja nie istnieje dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Pomyślnie usunięto niestandardową konfiguracje gry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Nie udało się usunąć niestandardowej konfiguracji gry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Wypakowanie RomFS nieudane!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Wystąpił błąd podczas kopiowania plików RomFS lub użytkownik anulował operację.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Pełny</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Szkielet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Wybierz tryb zrzutu RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Proszę wybrać w jaki sposób chcesz, aby zrzut pliku RomFS został wykonany. &lt;br&gt;Pełna kopia ze wszystkimi plikami do nowego folderu, gdy &lt;br&gt;skielet utworzy tylko strukturę folderu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Nie ma wystarczająco miejsca w %1 aby wyodrębnić RomFS.
Zwolnij trochę miejsca, albo zmień ścieżkę zrzutu RomFs w Emulacja&gt; Konfiguruj&gt; System&gt; System Plików&gt; Źródło Zrzutu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Wypakowywanie RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Anuluj</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Wypakowanie RomFS zakończone pomyślnie!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Operacja zakończona sukcesem.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Utwórz skrót</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Utworzy to skrót do obecnego AppImage. Może nie działać dobrze po aktualizacji. Kontynuować?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Nie można utworzyć skrótu na pulpicie. Ścieżka &quot;%1&quot; nie istnieje.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Nie można utworzyć skrótu w menu aplikacji. Ścieżka &quot;%1&quot; nie istnieje oraz nie może być utworzona.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Utwórz ikonę</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Nie można utworzyć pliku ikony. Ścieżka &quot;%1&quot; nie istnieje oraz nie może być utworzona.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Włącz %1 z emulatorem yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Nie udało się utworzyć skrótu pod %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Pomyślnie utworzono skrót do %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Błąd podczas otwierania %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Wybierz folder...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Właściwości</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Właściwości tej gry nie mogły zostać załadowane.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Plik wykonywalny Switcha (%1);;Wszystkie pliki (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Załaduj plik...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Otwórz folder wypakowanego ROMu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Wybrano niewłaściwy folder</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Folder wybrany przez ciebie nie zawiera &apos;głownego&apos; pliku.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Instalacyjne pliki Switch&apos;a (*.nca *.nsp *.xci);;Archiwum zawartości Nintendo (*.nca);;Pakiet poddany Nintendo (*.nsp);;Obraz z kartridża NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Zainstaluj pliki</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>1 plik został</numerusform><numerusform>%n plików zostało</numerusform><numerusform>%n plików zostało</numerusform><numerusform>%n plików zostało</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalowanie pliku &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Wynik instalacji</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Aby uniknąć ewentualnych konfliktów, odradzamy użytkownikom instalowanie gier na NAND.
Proszę, używaj tej funkcji tylko do instalowania łatek i DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>1 nowy plik został zainstalowany
@@ -4364,351 +4363,383 @@ Proszę, używaj tej funkcji tylko do instalowania łatek i DLC.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>1 plik został nadpisany</numerusform><numerusform>%n plików zostało nadpisane</numerusform><numerusform>%n plików zostało nadpisane</numerusform><numerusform>%n plików zostało nadpisane</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>1 pliku nie udało się zainstalować</numerusform><numerusform>%n plików nie udało się zainstalować</numerusform><numerusform>%n plików nie udało się zainstalować</numerusform><numerusform>%n plików nie udało się zainstalować</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Aplikacja systemowa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Archiwum systemu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Aktualizacja aplikacji systemowej</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Paczka systemowa (Typ A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Paczka systemowa (Typ B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Gra</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Aktualizacja gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Dodatek do gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Tytuł Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Wybierz typ instalacji NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Wybierz typ tytułu, do którego chcesz zainstalować ten NCA, jako:
(W większości przypadków domyślna &quot;gra&quot; jest w porządku.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Instalacja nieudana</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Typ tytułu wybrany dla NCA jest nieprawidłowy.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Nie znaleziono pliku</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Nie znaleziono pliku &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Wymagania sprzętowe nie są spełnione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Twój system nie spełnia rekomendowanych wymagań sprzętowych. Raportowanie kompatybilności zostało wyłączone.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Brakuje konta Yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Aby przesłać test zgodności gry, musisz połączyć swoje konto yuzu.&lt;br&gt;&lt;br/&gt; Aby połączyć swoje konto yuzu, przejdź do opcji Emulacja &amp;gt; Konfiguracja &amp;gt; Sieć.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Błąd otwierania adresu URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Nie można otworzyć adresu URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Nagrywanie TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Nadpisać plik gracza 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Wykryto nieprawidłową konfigurację</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Nie można używać kontrolera handheld w trybie zadokowanym. Zostanie wybrany kontroler Pro.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Amiibo zostało &quot;zdjęte&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Błąd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Ta gra nie szuka amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Plik Amiibo (%1);;Wszyskie pliki (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Załaduj Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Błąd podczas ładowania pliku danych Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Wybrany plik nie jest poprawnym amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Wybrany plik jest już w użyciu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Wystąpił nieznany błąd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Zrób zrzut ekranu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Obrazek PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Status TAS: Działa %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Status TAS: Nagrywa %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Status TAS: Bezczynny %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Status TAS: Niepoprawny</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Wyłącz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Przestań N&amp;agrywać</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>N&amp;agraj</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Budowanie shadera</numerusform><numerusform>Budowanie: %n shaderów</numerusform><numerusform>Budowanie: %n shaderów</numerusform><numerusform>Budowanie: %n shaderów</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Prędkość: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Prędkość: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Gra: %1 FPS (Odblokowane)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Gra: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Klatka: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>BEZ AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>Głośność: Wyciszony</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>Głośność: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Potwierdź ponowną aktywacje klucza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4725,37 +4756,37 @@ i opcjonalnie tworzyć kopie zapasowe.
Spowoduje to usunięcie wygenerowanych automatycznie plików kluczy i ponowne uruchomienie modułu pochodnego klucza.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Brakujące bezpieczniki</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - Brak BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Brak BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Brak PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Brak komponentów wyprowadzania</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Brakuje elementów, które mogą uniemożliwić zakończenie wyprowadzania kluczy. &lt;br&gt;Postępuj zgodnie z &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu quickstart guide&lt;/a&gt; aby zdobyć wszystkie swoje klucze i gry.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4764,49 +4795,49 @@ Zależnie od tego może potrwać do minuty
na wydajność twojego systemu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Wyprowadzanie kluczy...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Wybierz cel zrzutu RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Proszę wybrać RomFS, jakie chcesz zrzucić.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Czy na pewno chcesz zamknąć yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Czy na pewno chcesz zatrzymać emulację? Wszystkie niezapisane postępy zostaną utracone.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4958,241 +4989,251 @@ Czy chcesz to ominąć i mimo to wyjść?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Ulubione</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Uruchom grę</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Uruchom grę bez niestandardowej konfiguracji</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Otwórz lokalizację zapisów</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Otwórz lokalizację modyfikacji</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Otwórz Transferowalną Pamięć Podręczną Pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Usuń</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Usuń zainstalowaną łatkę</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Usuń wszystkie zainstalowane DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Usuń niestandardową konfigurację</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Usuń pamięć podręczną</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Usuń Pamięć Podręczną Pipeline OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Usuń Pamięć Podręczną Pipeline Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Usuń całą pamięć podręczną Pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Usuń całą zainstalowaną zawartość</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Zrzuć RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Zrzuć RomFS do SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Kopiuj identyfikator gry do schowka</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Nawiguj do wpisu kompatybilności gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Utwórz skrót</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Dodaj do pulpitu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Dodaj do menu aplikacji</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Właściwości</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Skanuj podfoldery</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Usuń katalog gier</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Przenieś w górę</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Przenieś w dół</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Otwórz lokalizacje katalogu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Wyczyść</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nazwa gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatybilność</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Dodatki</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Typ pliku</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Rozmiar</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>W grze</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Gra uruchamia się, ale awarie lub poważne błędy uniemożliwiają jej ukończenie.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfekcyjnie</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Można grać bez problemów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Grywalna</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Gra działa z drobnymi błędami graficznymi lub dźwiękowymi oraz jest grywalna od początku aż do końca.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Gra się ładuje, ale nie może przejść przez ekran początkowy.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Nie uruchamia się</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Ta gra się zawiesza przy próbie startu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Nie testowane</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Ta gra nie została jeszcze przetestowana.</translation>
</message>
@@ -5200,7 +5241,7 @@ Czy chcesz to ominąć i mimo to wyjść?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Kliknij podwójnie aby dodać folder do listy gier</translation>
</message>
@@ -5213,12 +5254,12 @@ Czy chcesz to ominąć i mimo to wyjść?</translation>
<translation><numerusform>1 z %n rezultatów</numerusform><numerusform>%1 z %n rezultatów</numerusform><numerusform>%1 z %n rezultatów</numerusform><numerusform>%1 z %n rezultatów</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filter:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Wpisz typ do filtra</translation>
</message>
@@ -5336,6 +5377,7 @@ Komunikat debugowania:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Okno główne</translation>
</message>
@@ -5441,6 +5483,11 @@ Komunikat debugowania:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Przełącz pasek stanu</translation>
</message>
@@ -5679,186 +5726,216 @@ Komunikat debugowania:</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Pomoc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Zainstaluj pliki na NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>Z&amp;aładuj Plik...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Załaduj &amp;Folder...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>&amp;Wyjście</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pauza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Stop</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Zainicjuj ponownie klucze...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;O yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Tryb &amp;Pojedyńczego Okna</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Kon&amp;figuruj...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Wyłącz Nagłówek Widżetu Docku</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Pokaż &amp;Pasek Filtrów</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Pokaż &amp;Pasek Statusu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Pokaż pasek statusu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Przeglądaj publiczne lobby gier</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Utwórz Pokój</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Wyjdź z Pokoju</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Bezpośrednie połączenie z pokojem</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Pokaż bieżący pokój</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>P&amp;ełny Ekran</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Restart</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Załaduj/Usuń &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Zraportuj Kompatybilność</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Otwórz &amp;Stronę z Modami</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Otwórz &amp;Poradnik Szybkiego Startu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Otwórz &amp;Folder yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Zrób Zdjęcie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Skonfiguruj TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Skonfiguruj O&amp;becną Grę...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Zresetuj</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>N&amp;agraj</translation>
</message>
@@ -6166,27 +6243,27 @@ p, li { white-space: pre-wrap; }
<translation>Nie gra w żadną grę</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Zainstalowane tytuły SD</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Zainstalowane tytuły NAND</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Tytuły systemu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Dodaj nowy katalog gier</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Ulubione</translation>
</message>
@@ -6712,7 +6789,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro kontroler</translation>
</message>
@@ -6725,7 +6802,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Para Joyconów</translation>
</message>
@@ -6738,7 +6815,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Lewy Joycon</translation>
</message>
@@ -6751,7 +6828,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Prawy Joycon</translation>
</message>
@@ -6780,7 +6857,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
@@ -6896,32 +6973,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Kontroler GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Kontroler NES/Pegasus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Kontroler SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Kontroler N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Mega Drive</translation>
</message>
diff --git a/dist/languages/pt_BR.ts b/dist/languages/pt_BR.ts
index e6265e41b..0bb294c85 100644
--- a/dist/languages/pt_BR.ts
+++ b/dist/languages/pt_BR.ts
@@ -36,7 +36,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Site&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Código fonte&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contribuidores&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Licença&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Site&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Código-fonte&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contribuidores&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Licença&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
@@ -373,13 +373,13 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Auto (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Padrão (%1)</translation>
@@ -834,7 +834,7 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="377"/>
<source>Enable Renderdoc Hotkey</source>
- <translation type="unfinished"/>
+ <translation>Habilitar atalho para Renderdoc</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="387"/>
@@ -893,49 +893,29 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Criar um despejo resumido após uma falha</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Habilite essa opção para gravar a última saída da lista de comandos de áudio para o console. Somente afetará jogos que utilizam o renderizador de áudio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Despejar comandos de áudio no console**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Ativar serviços de relatório detalhado**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Isto será restaurado automaticamente assim que o yuzu for fechado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>É necessário reiniciar</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>Será necessário reiniciar o yuzu para aplicar as configurações.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Applet Web não compilado</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Criação do mini despejo não compilada</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1354,7 +1334,7 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Combinação de teclas já utilizada</translation>
</message>
@@ -1375,27 +1355,37 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<translation>Inválido</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>Configurações de atalho inválidas</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation>Houve um erro. Relate o problema no GitHub.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Restaurar padrão</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Limpar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Sequência de botões conflitante</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>A sequência de botões padrão já está vinculada a %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>A sequência de teclas padrão já esta atribuida para: %1</translation>
</message>
@@ -3373,67 +3363,72 @@ Mova os pontos para mudar a posição, ou clique duas vezes nas células da tabe
<translation>Mostrar coluna de tipos de arquivos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>Exibir coluna Tempo jogado</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Tamanho do ícone do jogo:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Tamanho do ícone da pasta:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Texto da 1ª linha:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Texto da 2ª linha:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Capturas de tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Perguntar onde salvar capturas de tela (apenas Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Pasta para capturas de tela:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>TextLabel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Resolução:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Selecione a pasta de capturas de tela...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Auto (%1 x %2, %3 x %4)</translation>
@@ -3751,612 +3746,616 @@ Mova os pontos para mudar a posição, ou clique duas vezes nas células da tabe
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dados anônimos são recolhidos&lt;/a&gt; para ajudar a melhorar o yuzu. &lt;br/&gt;&lt;br/&gt;Gostaria de compartilhar os seus dados de uso conosco?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Detectada Instalação Defeituosa do Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>A inicialização do Vulkan falhou durante a carga do programa. &lt;br&gt;&lt;br&gt;Clique &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;aqui para instruções de como resolver o problema&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Rodando um jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Carregando applet web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Desativar o applet da web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>A desativação do applet da web pode causar comportamento inesperado e deve apenas ser usada com Super Mario 3D All-Stars. Você deseja mesmo desativar o applet da web?
(Ele pode ser reativado nas configurações de depuração.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>A quantidade de shaders sendo construídos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>O atualmente multiplicador de escala de resolução selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocidade atual de emulação. Valores maiores ou menores que 100% indicam que a emulação está rodando mais rápida ou lentamente que em um Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Quantos quadros por segundo o jogo está exibindo atualmente. Isto irá variar de jogo para jogo e cena para cena.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tempo que leva para emular um quadro do Switch, sem considerar o limitador de taxa de quadros ou a sincronização vertical. Um valor menor ou igual a 16.67 ms indica que a emulação está em velocidade plena.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Unmute</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Mudo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Redefinir volume</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Limpar arquivos recentes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Mouse emulado está habilitado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Controle de mouse real e controle panorâmico do mouse são incompatíveis. Por favor desabilite a emulação do mouse em configurações avançadas de controles para permitir o controle panorâmico do mouse.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Aviso - formato de jogo desatualizado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Você está usando neste jogo o formato de ROM desconstruída e extraída em uma pasta, que é um formato desatualizado que foi substituído por outros, como NCA, NAX, XCI ou NSP. Pastas desconstruídas de ROMs não possuem ícones, metadados e suporte a atualizações.&lt;br&gt;&lt;br&gt;Para saber mais sobre os vários formatos de ROMs de Switch compatíveis com o yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;confira a nossa wiki&lt;/a&gt;. Esta mensagem não será exibida novamente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Erro ao carregar a ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>O formato da ROM não é suportado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Ocorreu um erro ao inicializar o núcleo de vídeo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu encontrou um erro enquanto rodando o núcleo de vídeo. Normalmente isto é causado por drivers de GPU desatualizados, incluindo integrados. Por favor veja o registro para mais detalhes. Para mais informações em acesso ao registro por favor veja a seguinte página: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Como fazer envio de arquivo de registro&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Erro ao carregar a ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;o guia de início rápido&lt;/a&gt; para reextrair os seus arquivos.&lt;br&gt;Você pode consultar a wiki do yuzu&lt;/a&gt; ou o Discord do yuzu&lt;/a&gt; para obter ajuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ocorreu um erro desconhecido. Consulte o registro para mais detalhes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Encerrando software...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Dados de jogos salvos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Dados de mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Erro ao abrir a pasta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>A pasta não existe!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Erro ao abrir o cache de shaders transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Falha ao criar o diretório de cache de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Erro ao Remover Conteúdos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Erro ao Remover Atualização</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Erro ao Remover DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Remover Conteúdo Instalado do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Remover Atualização Instalada do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Remover DLC Instalada do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Remover item</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Removido com sucesso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>O jogo base foi removido com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>O jogo base não está instalado na NAND e não pode ser removido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>A atualização instalada foi removida com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Não há nenhuma atualização instalada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Não há nenhum DLC instalado para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 DLC(s) instalados foram removidos com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Apagar todos os caches de shaders transferíveis?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Remover configurações customizadas do jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Remover Armazenamento da Cache?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Remover arquivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>Remover dados de tempo jogado</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>Deseja mesmo resetar o tempo jogado?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Erro ao remover cache de shaders transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Não existe um cache de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>O cache de shaders transferível foi removido com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Falha ao remover o cache de shaders transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Erro ao Remover Cache de Pipeline do Driver Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Falha ao remover o pipeline de cache do driver.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Erro ao remover os caches de shaders transferíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Os caches de shaders transferíveis foram removidos com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Falha ao remover o diretório do cache de shaders transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Erro ao remover as configurações customizadas do jogo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Não há uma configuração customizada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>As configurações customizadas do jogo foram removidas com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Falha ao remover as configurações customizadas do jogo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Falha ao extrair RomFS!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Houve um erro ao copiar os arquivos RomFS ou o usuário cancelou a operação.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Extração completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Apenas estrutura</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Selecione o modo de extração do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Selecione a forma como você gostaria que o RomFS seja extraído.&lt;br&gt;&quot;Extração completa&quot; copiará todos os arquivos para a nova pasta, enquanto que &lt;br&gt;&quot;Apenas estrutura&quot; criará apenas a estrutura de pastas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Não há espaço suficiente em %1 para extrair o RomFS. Por favor abra espaço ou selecione um diretório diferente em Emulação &gt; Configurar &gt; Sistema &gt; Sistema de arquivos &gt; Extrair raiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Extraindo RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extração do RomFS concluida!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>A operação foi concluída com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
- <translation type="unfinished"/>
+ <translation>A verificação de integridade não foi realizada.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
- <translation type="unfinished"/>
+ <translation>O conteúdo do arquivo não foi analisado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
- <translation type="unfinished"/>
+ <translation>Houve uma falha na verificação de integridade!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
- <translation type="unfinished"/>
+ <translation>O conteúdo do arquivo pode estar corrompido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
- <translation type="unfinished"/>
+ <translation>Verificando integridade…</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
- <translation type="unfinished"/>
+ <translation>Verificação de integridade concluída!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Criar Atalho</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Isso irá criar um atalho para o AppImage atual. Isso pode não funcionar corretamente se você fizer uma atualização. Continuar?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Não foi possível criar um atalho na área de trabalho. O caminho &quot;%1&quot; não existe.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Não foi possível criar um atalho no menu de aplicativos. O caminho &quot;%1&quot; não existe e não pode ser criado.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>Não foi possível criar o atalho. O caminho &quot;%1&quot; não existe.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Criar Ícone</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Não foi possível criar o arquivo de ícone. O caminho &quot;%1&quot; não existe e não pode ser criado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Iniciar %1 com o emulador yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Falha ao criar um atalho em %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Atalho criado em %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Erro ao abrir %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Selecionar pasta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>As propriedades do jogo não puderam ser carregadas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Executável do Switch (%1);;Todos os arquivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Carregar arquivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Abrir pasta da ROM extraída</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Pasta inválida selecionada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>A pasta que você selecionou não contém um arquivo &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Arquivo de Switch instalável (*.nca *.nsp *.xci);; Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Instalar arquivos</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n arquivo restante</numerusform><numerusform>%n arquivo(s) restante(s)</numerusform><numerusform>%n arquivo(s) restante(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalando arquivo &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Resultados da instalação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Para evitar possíveis conflitos, desencorajamos que os usuários instalem os jogos base na NAND.
Por favor, use esse recurso apenas para instalar atualizações e DLCs.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n arquivo(s) instalado(s)
@@ -4365,7 +4364,7 @@ Por favor, use esse recurso apenas para instalar atualizações e DLCs.</transla
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n arquivo(s) sobrescrito(s)
@@ -4374,7 +4373,7 @@ Por favor, use esse recurso apenas para instalar atualizações e DLCs.</transla
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n arquivo(s) não instalado(s)
@@ -4383,339 +4382,373 @@ Por favor, use esse recurso apenas para instalar atualizações e DLCs.</transla
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Aplicativo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Arquivo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Atualização de aplicativo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Pacote de firmware (tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Pacote de firmware (tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Atualização de jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC de jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Título delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Selecione o tipo de instalação do NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Selecione o tipo de título como o qual você gostaria de instalar este NCA:
(Na maioria dos casos, o padrão &apos;Jogo&apos; serve bem.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Falha ao instalar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>O tipo de título que você selecionou para o NCA é inválido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Arquivo não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Arquivo &quot;%1&quot; não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Requisitos de hardware não atendidos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Seu sistema não atende os requisitos de harwdare. O relatório de compatibilidade foi desabilitado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Conta do yuzu faltando</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Para enviar um caso de teste de compatibilidade de jogo, você precisa entrar com a sua conta do yuzu.&lt;br&gt;&lt;br/&gt;Para isso, vá para Emulação &amp;gt; Configurar... &amp;gt; Rede.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Erro ao abrir URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Não foi possível abrir o URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Gravando TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Sobrescrever arquivo do jogador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Configuração inválida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>O controle portátil não pode ser usado no modo encaixado na base. O Pro Controller será selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>O amiibo atual foi removido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Erro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>O jogo atual não está procurando amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Arquivo Amiibo (%1);; Todos os arquivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Carregar Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Erro ao carregar dados do Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>O arquivo selecionado não é um amiibo válido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>O arquivo selecionado já está em uso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Ocorreu um erro desconhecido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
- <translation type="unfinished"/>
+ <translation>Houve uma falha na verificação dos seguintes arquivos:
+
+%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
- <translation type="unfinished"/>
+ <translation>Nenhum firmware disponível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>Instale o firmware para usar o applet Álbum.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>Applet Álbum</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>O applet Álbum não está disponível. Reinstale o firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>Instale o firmware para usar o applet Armário.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Applet Armário</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>O applet Armário não está disponível. Reinstale o firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
- <translation type="unfinished"/>
+ <translation>Instale o firmware para usar o applet Editor de Miis.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
- <translation type="unfinished"/>
+ <translation>Applet Editor de Miis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
- <translation type="unfinished"/>
+ <translation>O applet Editor de Miis não está disponível. Reinstale o firmware.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Capturar tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Imagem PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Situação TAS: Rodando %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Situação TAS: Gravando %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Situação TAS: Repouso %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Situação TAS: Inválido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar de rodar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Parar G&amp;ravação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravação</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Compilando: %n shader(s)</numerusform><numerusform>Compilando: %n shader(s)</numerusform><numerusform>Compilando: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Velocidade: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Velocidade: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Jogo: %1 FPS (Desbloqueado)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Jogo: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Quadro: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>Sem AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUME: MUDO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>VOLUME: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmar rederivação de chave</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4732,37 +4765,37 @@ e opcionalmente faça cópias de segurança.
Isto excluirá o seus arquivos de chaves geradas automaticamente, e reexecutar o módulo de derivação de chaves.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Faltando fusíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - Faltando BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Faltando BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Faltando PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Faltando componentes de derivação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Chaves de encriptação faltando. &lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;o guia de início rápido&lt;/a&gt; para extrair suas chaves, firmware e jogos. &lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4771,49 +4804,49 @@ Isto pode demorar até um minuto, dependendo
do desempenho do seu sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Derivando chaves</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Falha a desencriptar o arquivo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Chaves de encriptação falharam a desencriptar o firmware. &lt;br&gt;Por favor segue &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; para obter todas as tuas chaves, firmware e jogos.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Selecionar alvo de extração do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Selecione qual RomFS você quer extrair.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Você deseja mesmo fechar o yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Deseja mesmo parar a emulação? Qualquer progresso não salvo será perdido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4965,241 +4998,251 @@ Deseja ignorar isso e sair mesmo assim?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Favorito</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Iniciar jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Iniciar jogo sem configuração personalizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Abrir local dos jogos salvos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Abrir local dos dados de mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Abrir cache de pipeline transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Remover</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Remover atualização instalada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Remover todos os DLCs instalados</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Remover configuração customizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>Remover dados de tempo jogado</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Remover cache do armazenamento </translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Remover cache de pipeline do OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Remover cache de pipeline do Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Remover todos os caches de pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Remover todo o conteúdo instalado</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Extrair RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Extrair RomFS para SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
- <translation type="unfinished"/>
+ <translation>Verificar integridade</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Copiar ID do título para a área de transferência</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Abrir artigo do jogo no GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Criar atalho</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Adicionar à área de trabalho</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Adicionar ao menu de aplicativos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Examinar subpastas</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Remover pasta de jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Mover para cima</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Mover para baixo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Abrir local da pasta</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Limpar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nome</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Compatibilidade</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Adicionais</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Tipo de arquivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Tamanho</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>Tempo jogado</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Não Jogável</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>O jogo inicia, porém problemas ou grandes falhas impedem que ele seja concluído.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfeito</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>O jogo pode ser jogado sem problemas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Jogável</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>O jogo funciona com pequenas falhas gráficas ou de áudio e pode ser reproduzido do início ao fim.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>O jogo carrega, porém não consegue passar da tela inicial.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Não inicia</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>O jogo trava ou se encerra abruptamente ao se tentar iniciá-lo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Não testado</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Esse jogo ainda não foi testado.</translation>
</message>
@@ -5207,7 +5250,7 @@ Deseja ignorar isso e sair mesmo assim?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Clique duas vezes para adicionar uma pasta à lista de jogos</translation>
</message>
@@ -5220,12 +5263,12 @@ Deseja ignorar isso e sair mesmo assim?</translation>
<translation><numerusform>%1 de %n resultado(s)</numerusform><numerusform>%1 de %n resultado(s)</numerusform><numerusform>%1 de %n resultado(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filtro:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Digite o padrão para filtrar</translation>
</message>
@@ -5343,6 +5386,7 @@ Mensagem de depuração:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Janela principal</translation>
</message>
@@ -5448,6 +5492,11 @@ Mensagem de depuração:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Alternar Barra de Status</translation>
</message>
@@ -5686,186 +5735,216 @@ Mensagem de depuração:</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Ajuda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Instalar arquivos para NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>&amp;Carregar arquivo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Carregar &amp;pasta...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>S&amp;air</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Parar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Reinicializar chaves...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>&amp;Verificar conteúdo instalado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Sobre o yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Modo de &amp;janela única</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Con&amp;figurar...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Exibir barra de títul&amp;os de widgets afixados</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Exibir barra de &amp;filtro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Exibir barra de &amp;status</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Exibir barra de status</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Navegar no Lobby de Salas Públicas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Criar sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>Sai&amp;r da sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>Entrar &amp;diretamente numa sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>Mostrar &amp;sala atual</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>&amp;Tela cheia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Reiniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Carregar/Remover &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Reportar compatibilidade</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Abrir página de &amp;mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Abrir &amp;guia de início rápido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;Perguntas frequentes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Abrir pasta do &amp;yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Captura de tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>Abrir &amp;Álbum</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>&amp;Definir apelido e proprietário</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>&amp;Remover dados do jogo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>&amp;Recuperar Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>&amp;Formatar Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
- <translation type="unfinished"/>
+ <translation>Abrir &amp;Editor de Miis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Configurar TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Configurar jogo &amp;atual..</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Restaurar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravar</translation>
</message>
@@ -6173,27 +6252,27 @@ p, li { white-space: pre-wrap; }
<translation>Não está jogando um jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Títulos instalados no SD</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Títulos instalados na NAND</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Títulos do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Adicionar pasta de jogos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoritos</translation>
</message>
@@ -6719,7 +6798,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6732,7 +6811,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Par de Joycons</translation>
</message>
@@ -6745,7 +6824,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon esquerdo</translation>
</message>
@@ -6758,7 +6837,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon direito</translation>
</message>
@@ -6787,7 +6866,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Portátil</translation>
</message>
@@ -6903,32 +6982,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>Não há a quantidade mínima de controles</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Controle de GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poké Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Controle do NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Controle do SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Controle do Nintendo 64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Mega Drive</translation>
</message>
diff --git a/dist/languages/pt_PT.ts b/dist/languages/pt_PT.ts
index dc52afcbb..6b091db8c 100644
--- a/dist/languages/pt_PT.ts
+++ b/dist/languages/pt_PT.ts
@@ -373,13 +373,13 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Auto (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Padrão (%1)</translation>
@@ -826,7 +826,7 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="377"/>
<source>Enable Renderdoc Hotkey</source>
- <translation type="unfinished"/>
+ <translation>Habilitar atalho para Renderdoc</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="387"/>
@@ -885,49 +885,29 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Criar um despejo resumido após uma falha</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Habilite essa opção para gravar a última saída da lista de comandos de áudio para o console. Somente afetará jogos que utilizam o renderizador de áudio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Despejar comandos de áudio no console**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Ativar serviços de relatório detalhado**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Isto será restaurado automaticamente assim que o yuzu for fechado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>É necessário reiniciar</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>Será necessário reiniciar o yuzu para aplicar as configurações.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Applet Web não compilado</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Criação do mini despejo não compilada</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1346,7 +1326,7 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Sequência de teclas em conflito</translation>
</message>
@@ -1367,27 +1347,37 @@ Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translatio
<translation>Inválido</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>Configurações de atalho inválidas</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation>Houve um erro. Relate o problema no GitHub.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Restaurar Padrão</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Limpar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Sequência de botões conflitante</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>A sequência de botões padrão já está vinculada a %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>A sequência de teclas padrão já está atribuída a: %1</translation>
</message>
@@ -3365,67 +3355,72 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta
<translation>Exibir Coluna Tipos de Arquivos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>Exibir coluna Tempo jogado</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Tamanho do ícone do jogo:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Tamanho do ícone da pasta:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Linha 1 Texto:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Linha 2 Texto:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Captura de Ecrã</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Perguntar Onde Guardar Capturas de Ecrã (Apenas Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Caminho das Capturas de Ecrã:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>TextLabel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Resolução:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Seleccionar Caminho de Capturas de Ecrã...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Auto (%1 x %2, %3 x %4)</translation>
@@ -3743,962 +3738,1000 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dados anônimos são coletados&lt;/a&gt;para ajudar a melhorar o yuzu.&lt;br/&gt;&lt;br/&gt;Gostaria de compartilhar seus dados de uso conosco?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Detectada Instalação Defeituosa do Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>A inicialização do Vulkan falhou durante a carga do programa. &lt;br&gt;&lt;br&gt;Clique &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;aqui para instruções de como resolver o problema&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Rodando um jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>A Carregar o Web Applet ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Desativar Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>A desativação do applet da web pode causar comportamento inesperado e deve apenas ser usada com Super Mario 3D All-Stars. Você deseja mesmo desativar o applet da web?
(Ele pode ser reativado nas configurações de depuração.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Quantidade de shaders a serem construídos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>O atualmente multiplicador de escala de resolução selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocidade da emulação actual. Valores acima ou abaixo de 100% indicam que a emulação está sendo executada mais depressa ou mais devagar do que a Switch</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Quantos quadros por segundo o jogo está exibindo de momento. Isto irá variar de jogo para jogo e de cena para cena.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tempo gasto para emular um frame da Switch, sem contar o a limitação de quadros ou o v-sync. Para emulação de velocidade máxima, esta deve ser no máximo 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Unmute</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Mute</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Redefinir volume</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Limpar arquivos recentes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Mouse emulado está habilitado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Controle de mouse real e controle panorâmico do mouse são incompatíveis. Por favor desabilite a emulação do mouse em configurações avançadas de controles para permitir o controle panorâmico do mouse.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Aviso de Formato de Jogo Desactualizado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Você está usando o formato de directório ROM desconstruído para este jogo, que é um formato desactualizado que foi substituído por outros, como NCA, NAX, XCI ou NSP. Os directórios de ROM não construídos não possuem ícones, metadados e suporte de actualização.&lt;br&gt;&lt;br&gt;Para uma explicação dos vários formatos de Switch que o yuzu suporta,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Verifique a nossa Wiki&lt;/a&gt;. Esta mensagem não será mostrada novamente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Erro ao carregar o ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>O formato do ROM não é suportado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Ocorreu um erro ao inicializar o núcleo do vídeo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu encontrou um erro enquanto rodando o núcleo de vídeo. Normalmente isto é causado por drivers de GPU desatualizados, incluindo integrados. Por favor veja o registro para mais detalhes. Para mais informações em acesso ao registro por favor veja a seguinte página: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Como fazer envio de arquivo de registro&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Erro ao carregar a ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;a guia de início rápido do yuzu&lt;/a&gt; para fazer o redespejo dos seus arquivos.&lt;br&gt;Você pode consultar a wiki do yuzu&lt;/a&gt; ou o Discord do yuzu&lt;/a&gt; para obter ajuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ocorreu um erro desconhecido. Por favor, veja o log para mais detalhes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Encerrando software...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Save Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Erro ao abrir a pasta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>A Pasta não existe!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Erro ao abrir os Shader Cache transferíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Falha ao criar o diretório de cache de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Erro Removendo Conteúdos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Erro ao Remover Atualização</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Erro Removendo DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Remover Conteúdo Instalado do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Remover Atualização Instalada do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Remover DLC Instalada do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Remover Entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Removido com Sucesso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Removida a instalação do jogo base com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>O jogo base não está instalado no NAND e não pode ser removido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Removida a actualização instalada com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Não há actualização instalada neste título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Não há DLC instalado neste título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Removido DLC instalado %1 com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Apagar todos os caches de shaders transferíveis?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Remover Configuração Personalizada do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Remover Armazenamento da Cache?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Remover Ficheiro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>Remover dados de tempo jogado</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>Deseja mesmo resetar o tempo jogado?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Error ao Remover Cache de Shader Transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>O Shader Cache para este titulo não existe.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Removido a Cache de Shader Transferível com Sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Falha ao remover a cache de shader transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Erro ao Remover Cache de Pipeline do Driver Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Falha ao remover o pipeline de cache do driver.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Erro ao remover os caches de shaders transferíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Os caches de shaders transferíveis foram removidos com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Falha ao remover o diretório do cache de shaders transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Erro ao Remover Configuração Personalizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Não existe uma configuração personalizada para este titúlo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Removida a configuração personalizada do jogo com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Falha ao remover a configuração personalizada do jogo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>A Extração de RomFS falhou!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Houve um erro ao copiar os arquivos RomFS ou o usuário cancelou a operação.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Cheio</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Esqueleto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Selecione o modo de despejo do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Por favor, selecione a forma como você gostaria que o RomFS fosse despejado&lt;br&gt;Full irá copiar todos os arquivos para o novo diretório enquanto&lt;br&gt;skeleton criará apenas a estrutura de diretórios.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Não há espaço suficiente em %1 para extrair o RomFS. Por favor abra espaço ou selecione um diretório diferente em Emulação &gt; Configurar &gt; Sistema &gt; Sistema de arquivos &gt; Extrair raiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Extraindo o RomFS ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extração de RomFS Bem-Sucedida!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>A operação foi completa com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
- <translation type="unfinished"/>
+ <translation>A verificação de integridade não foi realizada.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
- <translation type="unfinished"/>
+ <translation>O conteúdo do arquivo não foi analisado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
- <translation type="unfinished"/>
+ <translation>Houve uma falha na verificação de integridade!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
- <translation type="unfinished"/>
+ <translation>O conteúdo do arquivo pode estar corrompido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
- <translation type="unfinished"/>
+ <translation>Verificando integridade…</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
- <translation type="unfinished"/>
+ <translation>Verificação de integridade concluída!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Criar Atalho</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Isso irá criar um atalho para o AppImage atual. Isso pode não funcionar corretamente se você fizer uma atualização. Continuar?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Não foi possível criar um atalho na área de trabalho. O caminho &quot;%1&quot; não existe.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Não foi possível criar um atalho no menu de aplicativos. O caminho &quot;%1&quot; não existe e não pode ser criado.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>Não foi possível criar o atalho. O caminho &quot;%1&quot; não existe.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Criar Ícone</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Não foi possível criar o arquivo de ícone. O caminho &quot;%1&quot; não existe e não pode ser criado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Iniciar %1 com o Emulador Yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Falha ao criar um atalho em %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Atalho criado com sucesso em %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Erro ao abrir %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Selecione o Diretório</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>As propriedades do jogo não puderam ser carregadas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Executáveis Switch (%1);;Todos os Ficheiros (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Carregar Ficheiro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Abrir o directório ROM extraído</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Diretório inválido selecionado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>O diretório que você selecionou não contém um arquivo &apos;Main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Ficheiro Switch Instalável (*.nca *.nsp *.xci);;Arquivo de Conteúdo Nintendo (*.nca);;Pacote de Envio Nintendo (*.nsp);;Imagem de Cartucho NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Instalar Ficheiros</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n arquivo restante</numerusform><numerusform>%n ficheiro(s) remanescente(s)</numerusform><numerusform>%n ficheiro(s) remanescente(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalando arquivo &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Instalar Resultados</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Para evitar possíveis conflitos, desencorajamos que os utilizadores instalem os jogos base na NAND.
Por favor, use esse recurso apenas para instalar atualizações e DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Aplicação do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Arquivo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Atualização do aplicativo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Pacote de Firmware (Tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Pacote de Firmware (Tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Actualização do Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC do Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Título Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Selecione o tipo de instalação do NCA ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Por favor, selecione o tipo de título que você gostaria de instalar este NCA como:
(Na maioria dos casos, o padrão &apos;Jogo&apos; é suficiente).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Falha na instalação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>O tipo de título que você selecionou para o NCA é inválido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Arquivo não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Arquivo &quot;%1&quot; não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Requisitos de hardware não atendidos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Seu sistema não atende os requisitos de harwdare. O relatório de compatibilidade foi desabilitado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Conta Yuzu Ausente</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Para enviar um caso de teste de compatibilidade de jogos, você deve vincular sua conta yuzu.&lt;br&gt;&lt;br/&gt;Para vincular sua conta yuzu, vá para Emulação &amp;gt; Configuração &amp;gt; Rede.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Erro ao abrir URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Não foi possível abrir o URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Gravando TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Sobrescrever arquivo do jogador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Configação inválida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>O comando portátil não pode ser usado no modo encaixado na base. O Pro controller será selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>O amiibo atual foi removido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Erro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>O jogo atual não está procurando amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Arquivo Amiibo (%1);; Todos os Arquivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Carregar Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Erro ao carregar dados do Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>O arquivo selecionado não é um amiibo válido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>O arquivo selecionado já está em uso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Ocorreu um erro desconhecido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
- <translation type="unfinished"/>
+ <translation>Houve uma falha na verificação dos seguintes arquivos:
+
+%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
- <translation type="unfinished"/>
+ <translation>Nenhum firmware disponível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>Instale o firmware para usar o applet Album.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>Applet Álbum</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>O applet Álbum não está disponível. Reinstale o firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>Instale o firmware para usar o applet Armário.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Applet Armário</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>O applet Armário não está disponível. Reinstale o firmware.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
- <translation type="unfinished"/>
+ <translation>Instale o firmware para usar o applet Editor de Miis.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
- <translation type="unfinished"/>
+ <translation>Applet Editor de Miis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
- <translation type="unfinished"/>
+ <translation>O applet Editor de Miis não está disponível. Reinstale o firmware.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Captura de Tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Imagem PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Situação TAS: Rodando %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Situação TAS: Gravando %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Situação TAS: Repouso %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Situação TAS: Inválido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar de rodar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Começar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Parar G&amp;ravação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravação</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Velocidade: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Velocidade: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Jogo: %1 FPS (Desbloqueado)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Jogo: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Quadro: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>Sem AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>VOLUME: MUDO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>VOLUME: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Confirme a rederivação da chave</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4715,37 +4748,37 @@ e opcionalmente faça backups.
Isso irá excluir os seus arquivos de chave gerados automaticamente e executará novamente o módulo de derivação de chave.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Fusíveis em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- BOOT0 em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- BCPKG2-1-Normal-Main em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Componentes de Derivação em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Chaves de encriptação faltando. &lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;o guia de início rápido&lt;/a&gt; para extrair suas chaves, firmware e jogos. &lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4754,49 +4787,49 @@ Isto pode demorar até um minuto, dependendo
do desempenho do seu sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Derivando Chaves</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Falha a desencriptar o arquivo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Chaves de encriptação falharam a desencriptar o firmware. &lt;br&gt;Por favor segue &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; para obter todas as tuas chaves, firmware e jogos.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Selecione o destino de despejo do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Por favor, selecione qual o RomFS que você gostaria de despejar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Tem a certeza que quer fechar o yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Tem a certeza de que quer parar a emulação? Qualquer progresso não salvo será perdido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4948,241 +4981,251 @@ Deseja ignorar isso e sair mesmo assim?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Favorito</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Iniciar jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Iniciar jogo sem configuração personalizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Abrir Localização de Dados Salvos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Abrir a Localização de Dados do Mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Abrir cache de pipeline transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Remover</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Remover Actualizações Instaladas</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Remover Todos os DLC Instalados</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Remover Configuração Personalizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>Remover dados de tempo jogado</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Remove a Cache do Armazenamento </translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Remover cache de pipeline do OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Remover cache de pipeline do Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Remover todos os caches de pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Remover Todos os Conteúdos Instalados</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Despejar RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Extrair RomFS para SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
- <translation type="unfinished"/>
+ <translation>Verificar integridade</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Copiar título de ID para a área de transferência</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Navegue para a Entrada da Base de Dados de Jogos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Criar Atalho</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Adicionar à Área de Trabalho</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Adicionar ao Menu de Aplicativos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Examinar Sub-pastas</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Remover diretório do Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Mover para Cima</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Mover para Baixo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Abrir Localização do diretório</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Limpar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Nome</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Compatibilidade</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Add-ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Tipo de Arquivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Tamanho</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>Tempo jogado</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Não Jogável</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>O jogo inicia, porém problemas ou grandes falhas impedem que ele seja concluído.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfeito</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>O jogo pode ser jogado sem problemas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Jogável</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>O jogo funciona com pequenas falhas gráficas ou de áudio e pode ser reproduzido do início ao fim.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Introdução / Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>O jogo carrega, porém não consegue passar da tela inicial.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Não Inicia</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>O jogo trava ao tentar iniciar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Não Testado</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>O jogo ainda não foi testado.</translation>
</message>
@@ -5190,7 +5233,7 @@ Deseja ignorar isso e sair mesmo assim?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Clique duas vezes para adicionar uma nova pasta à lista de jogos</translation>
</message>
@@ -5203,12 +5246,12 @@ Deseja ignorar isso e sair mesmo assim?</translation>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filtro:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Digite o padrão para filtrar</translation>
</message>
@@ -5326,6 +5369,7 @@ Mensagem de depuração:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Janela Principal</translation>
</message>
@@ -5431,6 +5475,11 @@ Mensagem de depuração:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Alternar Barra de Status</translation>
</message>
@@ -5669,186 +5718,216 @@ Mensagem de depuração:</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>&amp;Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Ajuda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Instalar arquivos na NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>C&amp;arregar arquivo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Carregar &amp;pasta...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>&amp;Sair</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Parar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Reinicializar chaves...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
- <translation type="unfinished"/>
+ <translation>&amp;Verificar conteúdo instalado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Sobre o yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Modo de &amp;janela única</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Con&amp;figurar...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Exibir barra de títul&amp;os de widgets afixados</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Mostrar Barra de &amp;Filtros</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Mostrar Barra de &amp;Estado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Mostrar Barra de Estado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Navegar no Lobby de Salas Públicas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Criar Sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Sair da Sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>Conectar &amp;Diretamente Numa Sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>Exibir &amp;Sala Atual</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>T&amp;ela cheia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Reiniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Carregar/Remover &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Reportar compatibilidade</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Abrir Página de &amp;Mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Abrir &amp;guia de início rápido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;Perguntas frequentes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Abrir pasta &amp;yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Captura de Tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>Abrir &amp;Álbum</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>&amp;Definir apelido e proprietário</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>&amp;Remover dados do jogo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>&amp;Recuperar Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>&amp;Formatar Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
- <translation type="unfinished"/>
+ <translation>Abrir &amp;Editor de Miis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Configurar TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Configurar jogo atual...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Começar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Restaurar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravar</translation>
</message>
@@ -6155,27 +6234,27 @@ p, li { white-space: pre-wrap; }
<translation>Não está jogando um jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Títulos SD instalados</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Títulos NAND instalados</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Títulos do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Adicionar novo diretório de jogos</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoritos</translation>
</message>
@@ -6701,7 +6780,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Comando Pro</translation>
</message>
@@ -6714,7 +6793,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Par de Joycons</translation>
</message>
@@ -6727,7 +6806,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon Esquerdo</translation>
</message>
@@ -6740,7 +6819,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon Direito</translation>
</message>
@@ -6769,7 +6848,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Portátil</translation>
</message>
@@ -6885,32 +6964,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>Não há a quantidade mínima de controles</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Controlador de depuração</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poké Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Controle do NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Controle do SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Controle do Nintendo 64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Mega Drive</translation>
</message>
diff --git a/dist/languages/ru_RU.ts b/dist/languages/ru_RU.ts
index a8432bf83..80cf2078c 100644
--- a/dist/languages/ru_RU.ts
+++ b/dist/languages/ru_RU.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Авто (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>По умолчанию (%1)</translation>
@@ -893,49 +893,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Создавать мини-дамп после краша</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Включите эту опцию, чтобы вывести на консоль последний сгенерированный список аудиокоманд. Влияет только на игры, использующие аудио рендерер.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Дамп аудиокоманд в консоль**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Включить службу отчётов в развернутом виде**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Это будет автоматически сброшено после закрытия yuzu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Требуется перезапуск</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu необходимо перезапустить, чтобы применить эту настройку.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Веб-апплет не скомпилирован</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Создание мини-дампа не скомпилировано</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1354,7 +1334,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Конфликтующее сочетание клавиш</translation>
</message>
@@ -1375,27 +1355,37 @@ This would ban both their forum username and their IP address.</source>
<translation>Недопустимо</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Ввостановить значение по умолчанию</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Очистить</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Конфликтующее сочетание кнопок</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Сочетание кнопок по умолчанию уже назначено на: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Сочетание клавиш по умолчанию уже назначено на: %1</translation>
</message>
@@ -3373,67 +3363,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Показвыать столбец типа файлов</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Размер иконки игры:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Размер иконки папки:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Текст 1-ой строки:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Текст 2-ой строки:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Скриншоты</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Спрашивать куда сохранять скриншоты (Только для Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Папка для скриншотов:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Разрешение:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Выберите папку для скриншотов...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3751,612 +3746,616 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Анонимные данные собираются для того,&lt;/a&gt; чтобы помочь улучшить работу yuzu. &lt;br/&gt;&lt;br/&gt;Хотели бы вы делиться данными об использовании с нами?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Телеметрия</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Обнаружена поврежденная установка Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Не удалось выполнить инициализацию Vulkan во время загрузки.&lt;br&gt;&lt;br&gt;Нажмите &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;здесь для получения инструкций по устранению проблемы&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Запущена игра</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Загрузка веб-апплета...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Отключить веб-апплет</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Отключение веб-апплета может привести к неожиданному поведению и должно использоваться только с Super Mario 3D All-Stars. Вы уверены, что хотите отключить веб-апплет?
(Его можно снова включить в настройках отладки.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Количество создаваемых шейдеров на данный момент</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Текущий выбранный множитель масштабирования разрешения.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Текущая скорость эмуляции. Значения выше или ниже 100% указывают на то, что эмуляция идет быстрее или медленнее, чем на Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Количество кадров в секунду в данный момент. Значение будет меняться между играми и сценами.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Время, которое нужно для эмуляции 1 кадра Switch, не принимая во внимание ограничение FPS или вертикальную синхронизацию. Для эмуляции в полной скорости значение должно быть не больше 16,67 мс.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Включить звук</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Выключить звук</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Сбросить громкость</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>[&amp;C] Очистить недавние файлы</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Эмулированная мышь включена</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Ввод реальной мыши и панорамирование мышью несовместимы. Пожалуйста, отключите эмулированную мышь в расширенных настройках ввода, чтобы разрешить панорамирование мышью.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>[&amp;C] Продолжить</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>[&amp;P] Пауза</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Предупреждение устаревший формат игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Для этой игры вы используете разархивированный формат ROM&apos;а, который является устаревшим и был заменен другими, такими как NCA, NAX, XCI или NSP. В разархивированных каталогах ROM&apos;а отсутствуют иконки, метаданные и поддержка обновлений. &lt;br&gt;&lt;br&gt;Для получения информации о различных форматах Switch, поддерживаемых yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;просмотрите нашу вики&lt;/a&gt;. Это сообщение больше не будет отображаться.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Ошибка при загрузке ROM&apos;а!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Формат ROM&apos;а не поддерживается.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Произошла ошибка при инициализации видеоядра.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu столкнулся с ошибкой при запуске видеоядра. Обычно это вызвано устаревшими драйверами ГП, включая интегрированные. Проверьте журнал для получения более подробной информации. Дополнительную информацию о доступе к журналу смотрите на следующей странице: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Как загрузить файл журнала&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Ошибка при загрузке ROM&apos;а! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Пожалуйста, следуйте &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;краткому руководству пользователя yuzu&lt;/a&gt; чтобы пере-дампить ваши файлы&lt;br&gt;Вы можете обратиться к вики yuzu&lt;/a&gt; или Discord yuzu&lt;/a&gt; для помощи.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Произошла неизвестная ошибка. Пожалуйста, проверьте журнал для подробностей.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-х битный)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-х битный)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Закрываем программу...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Сохранения</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Данные модов</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Ошибка при открытии папки %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Папка не существует!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Ошибка при открытии переносного кэша шейдеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Не удалось создать папку кэша шейдеров для этой игры.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Ошибка при удалении содержимого</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Ошибка при удалении обновлений</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Ошибка при удалении DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Удалить установленное содержимое игр?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Удалить установленные обновления игры?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Удалить установленные DLC игры?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Удалить запись</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Успешно удалено</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Установленная игра успешно удалена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Игра не установлена в NAND и не может быть удалена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Установленное обновление успешно удалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Для этой игры не было установлено обновление.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Для этой игры не были установлены DLC.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Установленное DLC %1 было успешно удалено</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Удалить переносной кэш шейдеров OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Удалить переносной кэш шейдеров Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Удалить весь переносной кэш шейдеров?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Удалить пользовательскую настройку игры?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Удалить кэш-хранилище?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Удалить файл</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Ошибка при удалении переносного кэша шейдеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Кэш шейдеров для этой игры не существует.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Переносной кэш шейдеров успешно удалён.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Не удалось удалить переносной кэш шейдеров.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Ошибка при удалении конвейерного кэша Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Не удалось удалить конвейерный кэш шейдеров.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Ошибка при удалении переносного кэша шейдеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Переносной кэш шейдеров успешно удален.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Ошибка при удалении папки переносного кэша шейдеров.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Ошибка при удалении пользовательской настройки</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Пользовательская настройка для этой игры не существует.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Пользовательская настройка игры успешно удалена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Не удалось удалить пользовательскую настройку игры.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Не удалось извлечь RomFS!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Произошла ошибка при копировании файлов RomFS или пользователь отменил операцию.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Полный</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Скелет</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Выберите режим дампа RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Пожалуйста, выберите, как вы хотите выполнить дамп RomFS. &lt;br&gt;Полный скопирует все файлы в новую папку, в то время как &lt;br&gt;скелет создаст только структуру папок.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>В %1 недостаточно свободного места для извлечения RomFS. Пожалуйста, освободите место или выберите другую папку для дампа в Эмуляция &gt; Настройка &gt; Система &gt; Файловая система &gt; Корень дампа</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Извлечение RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Отмена</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Извлечение RomFS прошло успешно!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Операция выполнена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Создать ярлык</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Это создаст ярлык для текущего AppImage. Он может не работать после обновлений. Продолжить?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Не удается создать ярлык на рабочем столе. Путь &quot;%1&quot; не существует.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Невозможно создать ярлык в меню приложений. Путь &quot;%1&quot; не существует и не может быть создан.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Создать иконку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Невозможно создать файл иконки. Путь &quot;%1&quot; не существует и не может быть создан.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Запустить %1 с помощью эмулятора yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Не удалось создать ярлык в %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Успешно создан ярлык в %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Ошибка открытия %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Выбрать папку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Свойства</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Не удалось загрузить свойства игры.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Исполняемый файл Switch (%1);;Все файлы (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Загрузить файл</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Открыть папку извлечённого ROM&apos;а</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Выбрана недопустимая папка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Папка, которую вы выбрали, не содержит файла &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Устанавливаемый файл Switch (*.nca, *.nsp, *.xci);;Архив контента Nintendo (*.nca);;Пакет подачи Nintendo (*.nsp);;Образ картриджа NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Установить файлы</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>Остался %n файл</numerusform><numerusform>Осталось %n файл(ов)</numerusform><numerusform>Осталось %n файл(ов)</numerusform><numerusform>Осталось %n файл(ов)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Установка файла &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Результаты установки</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Чтобы избежать возможных конфликтов, мы не рекомендуем пользователям устанавливать игры в NAND.
Пожалуйста, используйте эту функцию только для установки обновлений и DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n файл был недавно установлен
@@ -4366,7 +4365,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n файл был перезаписан
@@ -4376,7 +4375,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n файл не удалось установить
@@ -4386,339 +4385,371 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Системное приложение</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Системный архив</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Обновление системного приложения</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Пакет прошивки (Тип А)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Пакет прошивки (Тип Б)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Игра</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Обновление игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Дельта-титул</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Выберите тип установки NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Пожалуйста, выберите тип приложения, который вы хотите установить для этого NCA:
(В большинстве случаев, подходит стандартный выбор «Игра».)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Ошибка установки</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Тип приложения, который вы выбрали для NCA, недействителен.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Файл не найден</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Файл &quot;%1&quot; не найден</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>ОК</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Не удовлетворены системные требования</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Ваша система не соответствует рекомендуемым системным требованиям. Отчеты о совместимости были отключены.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Отсутствует аккаунт yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Чтобы отправить отчет о совместимости игры, необходимо привязать свою учетную запись yuzu.&lt;br&gt;&lt;br/&gt;Чтобы привязать свою учетную запись yuzu, перейдите в раздел Эмуляция &amp;gt; Параметры &amp;gt; Сеть.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Ошибка при открытии URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Не удалось открыть URL: &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Запись TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Перезаписать файл игрока 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Обнаружена недопустимая конфигурация</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Портативный контроллер не может быть использован в режиме док-станции. Будет выбран контроллер Pro.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Текущий amiibo был убран</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Ошибка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Текущая игра не ищет amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Файл Amiibo (%1);; Все Файлы (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Загрузить Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Ошибка загрузки данных Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Выбранный файл не является допустимым amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Выбранный файл уже используется</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Произошла неизвестная ошибка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Сделать скриншот</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Изображение PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Состояние TAS: Выполняется %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Состояние TAS: Записывается %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Состояние TAS: Простой %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Состояние TAS: Неверное</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>[&amp;S] Остановка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>[&amp;S] Начать</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>[&amp;E] Закончить запись</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>[&amp;E] Запись</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Постройка: %n шейдер</numerusform><numerusform>Постройка: %n шейдер(ов)</numerusform><numerusform>Постройка: %n шейдер(ов)</numerusform><numerusform>Постройка: %n шейдер(ов)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Масштаб: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Скорость: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Скорость: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Игра: %1 FPS (Неограниченно)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Игра: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Кадр: %1 мс</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>БЕЗ СГЛАЖИВАНИЯ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>ГРОМКОСТЬ: ЗАГЛУШЕНА</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>ГРОМКОСТЬ: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Подтвердите перерасчет ключа</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4735,37 +4766,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
Это удалит ваши автоматически сгенерированные файлы ключей и повторно запустит модуль расчета ключей.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Отсутствуют предохранители</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Отсутствует BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Отсутствует BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- Отсутствует PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Компоненты расчета отсутствуют</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Ключи шифрования отсутствуют. &lt;br&gt;Пожалуйста, следуйте &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;краткому руководству пользователя yuzu&lt;/a&gt;, чтобы получить все ваши ключи, прошивку и игры.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4774,49 +4805,49 @@ on your system&apos;s performance.</source>
от производительности вашей системы.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Получение ключей</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Не удалось расшифровать системный архив</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Ключи шифрования не смогли расшифровать прошивку. &lt;br&gt;Пожалуйста, следуйте &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;краткому руководству пользователя yuzu&lt;/a&gt; чтобы получить все ваши ключи, прошивку и игры.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Выберите цель для дампа RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Пожалуйста, выберите, какой RomFS вы хотите сдампить.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Вы уверены, что хотите закрыть yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Вы уверены, что хотите остановить эмуляцию? Любой несохраненный прогресс будет потерян.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4968,241 +4999,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Избранное</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Запустить игру</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Запустить игру без пользовательской настройки</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Открыть папку для сохранений</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Открыть папку для модов</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Открыть переносной кэш конвейера</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Удалить</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Удалить установленное обновление</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Удалить все установленные DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Удалить пользовательскую настройку</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Удалить кэш-хранилище?</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Удалить кэш конвейера OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Удалить кэш конвейера Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Удалить весь кэш конвейеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Удалить все установленное содержимое</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Дамп RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Сдампить RomFS в SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Скопировать ID приложения в буфер обмена</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Перейти к странице GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Создать ярлык</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Добавить на Рабочий стол</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Добавить в меню приложений</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Свойства</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Сканировать подпапки</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Удалить папку с играми</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Переместить вверх</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Переместить вниз</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Открыть расположение папки</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Очистить</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Имя</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Совместимость</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Дополнения</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Тип файла</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Размер</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Запускается</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Игра запускается, но вылеты или серьезные баги не позволяют ее завершить.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Идеально</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>В игру можно играть без проблем.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Играбельно</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Игра работает с незначительными графическими и/или звуковыми ошибками и проходима от начала до конца.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Вступление/Меню</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Игра загружается, но не проходит дальше стартового экрана.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Не запускается</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Игра вылетает при запуске.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Не проверено</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Игру ещё не проверяли на совместимость.</translation>
</message>
@@ -5210,7 +5251,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Нажмите дважды, чтобы добавить новую папку в список игр</translation>
</message>
@@ -5223,12 +5264,12 @@ Would you like to bypass this and exit anyway?</source>
<translation><numerusform>%1 из %n результат(ов)</numerusform><numerusform>%1 из %n результат(ов)</numerusform><numerusform>%1 из %n результат(ов)</numerusform><numerusform>%1 из %n результат(ов)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Поиск:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Введите текст для поиска</translation>
</message>
@@ -5346,6 +5387,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Основное окно</translation>
</message>
@@ -5451,6 +5493,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Переключить панель состояния</translation>
</message>
@@ -5689,186 +5736,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>[&amp;T] TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>[&amp;H] Помощь</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>[&amp;I] Установить файлы в NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>[&amp;O] Загрузить файл...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>[&amp;F] Загрузить папку...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>[&amp;X] Выход</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>[&amp;P] Пауза</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>[&amp;S] Стоп</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>[&amp;R] Переинициализировать ключи...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>[&amp;A] О yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>[&amp;W] Режим одного окна</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>[&amp;F] Параметры...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>[&amp;O] Отображать заголовки виджетов дока</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>[&amp;F] Показать панель поиска</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>[&amp;S] Показать панель статуса</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Показать панель статуса</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>[&amp;B] Просмотреть публичные игровые лобби</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>[&amp;C] Создать комнату</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>[&amp;L] Покинуть комнату</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>[&amp;D] Прямое подключение к комнате</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>[&amp;S] Показать текущую комнату</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>[&amp;U] Полноэкранный</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>[&amp;R] Перезапустить</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>[&amp;A] Загрузить/Удалить Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>[&amp;R] Сообщить о совместимости</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>[&amp;M] Открыть страницу модов</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>[&amp;Q] Открыть руководство пользователя</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>[&amp;F] ЧАВО</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>[&amp;Y] Открыть папку yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>[&amp;C] Сделать скриншот</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>[&amp;C] Настройка TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>[&amp;U] Настроить текущую игру...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>[&amp;S] Запустить</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>[&amp;S] Сбросить</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>[&amp;E] Запись</translation>
</message>
@@ -6176,27 +6253,27 @@ p, li { white-space: pre-wrap; }
<translation>Не играет в игру</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Установленные SD игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Установленные NAND игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Системные игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Добавить новую папку с играми</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Избранные</translation>
</message>
@@ -6722,7 +6799,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Контроллер Pro</translation>
</message>
@@ -6735,7 +6812,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Двойные Joy-Сon&apos;ы</translation>
</message>
@@ -6748,7 +6825,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Левый Joy-Сon</translation>
</message>
@@ -6761,7 +6838,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Правый Joy-Сon</translation>
</message>
@@ -6790,7 +6867,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Портативный</translation>
</message>
@@ -6906,32 +6983,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Контроллер GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Контроллер NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Контроллер SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Контроллер N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/sv.ts b/dist/languages/sv.ts
index 886b9de52..bda3c05f5 100644
--- a/dist/languages/sv.ts
+++ b/dist/languages/sv.ts
@@ -373,13 +373,13 @@ Detta kommer bannlysa både dennes användarnamn på forum samt IP-adress.</tran
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -879,49 +879,29 @@ avgjord kod.&lt;/div&gt;
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation type="unfinished"/>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation type="unfinished"/>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1340,7 +1320,7 @@ avgjord kod.&lt;/div&gt;
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Motstridig Tangentsekvens</translation>
</message>
@@ -1361,27 +1341,37 @@ avgjord kod.&lt;/div&gt;
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Återställ standard</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Rensa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Standardtangentsekvensen är redan tilldelad: %1</translation>
</message>
@@ -3356,67 +3346,72 @@ Dra punkter för att ändra position, eller dubbelklicka tabellceller för att r
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Rad 1 Text:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Rad 2 Text:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Skrämdump</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Fråga till var man ska spara skärmdumpar (endast Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Skärmdumpssökväg</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Välj Skärmdumpssökväg...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3734,960 +3729,996 @@ Dra punkter för att ändra position, eller dubbelklicka tabellceller för att r
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonym data skickas &lt;/a&gt;För att förbättra yuzu. &lt;br/&gt;&lt;br/&gt;Vill du dela med dig av din användarstatistik med oss?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Felaktig Vulkaninstallation Upptäckt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Laddar WebApplet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Avaktivera Webbappletten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Mängden shaders som just nu byggs</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Nuvarande emuleringshastighet. Värden över eller under 100% indikerar på att emulationen körs snabbare eller långsammare än en Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Hur många bilder per sekund som spelet just nu visar. Detta varierar från spel till spel och scen till scen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tid det tar att emulera en Switch bild, utan att räkna med framelimiting eller v-sync. För emulering på full hastighet så ska det vara som mest 16.67 ms. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Emulerad datormus är aktiverad</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Paus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Varning Föråldrat Spelformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Du använder det dekonstruerade ROM-formatet för det här spelet. Det är ett föråldrat format som har överträffats av andra som NCA, NAX, XCI eller NSP. Dekonstruerade ROM-kataloger saknar ikoner, metadata och uppdatering.&lt;br&gt;&lt;br&gt;För en förklaring av de olika format som yuzu stöder, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;kolla in vår wiki&lt;/a&gt;. Det här meddelandet visas inte igen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Fel vid laddning av ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>ROM-formatet stöds inte.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Ett fel inträffade vid initiering av videokärnan.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ett okänt fel har uppstått. Se loggen för mer information.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Spardata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod-data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Fel Öppnar %1 Mappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Mappen finns inte!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Fel Under Öppning Av Överförbar Shadercache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Ta bort katalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Framgångsrikt borttagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Tog bort det installerade basspelet framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Basspelet är inte installerat i NAND och kan inte tas bort.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Tog bort den installerade uppdateringen framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Det finns ingen uppdatering installerad för denna titel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Det finns inga DLC installerade för denna titel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Tog framgångsrikt bort den %1 installerade DLCn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Ta Bort Anpassad Spelkonfiguration?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Radera fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Fel När Överförbar Shader Cache Raderades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>En shader cache för denna titel existerar inte.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Raderade den överförbara shadercachen framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Misslyckades att ta bort den överförbara shadercache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Fel När Anpassad Konfiguration Raderades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>En anpassad konfiguration för denna titel existerar inte.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Tog bort den anpassade spelkonfigurationen framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Misslyckades att ta bort den anpassade spelkonfigurationen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS Extraktion Misslyckades!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Det uppstod ett fel vid kopiering av RomFS filer eller användaren avbröt operationen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Full</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Skelett</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Välj RomFS Dump-Läge</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Välj hur du vill att RomFS ska dumpas. &lt;br&gt;Full kommer att kopiera alla filer i den nya katalogen medan &lt;br&gt;skelett bara skapar katalogstrukturen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Extraherar RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS Extraktion Lyckades!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Operationen var lyckad.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Fel under öppning av %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Välj Katalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Egenskaper</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Spelegenskaperna kunde inte laddas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Körbar (%1);;Alla Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Ladda Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Öppna Extraherad ROM-Katalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Ogiltig Katalog Vald</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Katalogen du har valt innehåller inte en &apos;main&apos;-fil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Installerbar Switch-fil (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Installera filer</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installerar Fil &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Installera resultat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Systemapplikation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Systemarkiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Systemapplikationsuppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Firmwarepaket (Typ A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Firmwarepaket (Typ B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Spel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Speluppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Spel DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Välj NCA-Installationsläge...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Välj vilken typ av titel du vill installera som:
(I de flesta fallen, standard &apos;Spel&apos; är bra.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Misslyckades med Installationen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Den titeltyp du valt för NCA är ogiltig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Filen hittades inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Filen &quot;%1&quot; hittades inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation> Hårdvarukraven uppfylls ej</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>yuzu Konto hittades inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>För att skicka ett spelkompatibilitetstest, du måste länka ditt yuzu-konto.&lt;br&gt;&lt;br/&gt;För att länka ditt yuzu-konto, gå till Emulering &amp;gt, Konfigurering &amp;gt, Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Fel när URL öppnades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Oförmögen att öppna URL:en &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS Inspelning</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Överskriv spelare 1:s fil?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Ogiltig konfiguration upptäckt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Den aktuella amiibon har avlägsnats</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Fel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Det aktuella spelet letar ej efter amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo Fil (%1);; Alla Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Ladda Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Fel vid laddning av Amiibodata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Den valda filen är inte en giltig amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Den valda filen är redan använd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Ett okänt fel har inträffat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Skärmdump</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG Bild (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAStillstånd: pågående %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAStillstånd: spelar in %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAStillstånd: inaktiv %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAStillstånd: ogiltigt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Hastighet: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Hastighet: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Spel: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Ruta: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Bekräfta Nyckel Rederivering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4704,37 +4735,37 @@ och eventuellt göra säkerhetskopior.
Detta raderar dina autogenererade nyckelfiler och kör nyckelderivationsmodulen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Saknade säkringar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Saknar BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Saknar BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- Saknar PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Deriveringsdelar saknas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4743,49 +4774,49 @@ Detta kan ta upp till en minut beroende
på systemets prestanda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Härleda Nycklar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Välj RomFS Dumpa Mål</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Välj vilken RomFS du vill dumpa.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Är du säker på att du vill stänga yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Är du säker på att du vill stoppa emuleringen? Du kommer att förlora osparade framsteg.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4937,241 +4968,251 @@ Vill du strunta i detta och avsluta ändå?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Öppna Spara Data Destination</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Öppna Mod Data Destination</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Ta Bort</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Ta Bort Installerad Uppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Ta Bort Alla Installerade DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Ta Bort Anpassad Konfiguration</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Ta Bort Allt Installerat Innehåll</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Dumpa RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Kopiera Titel ID till Urklipp</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Navigera till GameDB-sida</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Egenskaper</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Skanna Underkataloger</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Radera Spelkatalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Flytta upp</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Flytta ner</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Öppna Sökvägsplats</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Rensa</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Namn</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Kompatibilitet</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Add-Ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Filtyp</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Storlek</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Perfekt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Intro/Meny</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Startar Inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Spelet kraschar när man försöker starta det.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Inte Testad</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Spelet har ännu inte testats.</translation>
</message>
@@ -5179,7 +5220,7 @@ Vill du strunta i detta och avsluta ändå?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Dubbelklicka för att lägga till en ny mapp i spellistan.</translation>
</message>
@@ -5192,12 +5233,12 @@ Vill du strunta i detta och avsluta ändå?</translation>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filter:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Ange mönster för att filtrera</translation>
</message>
@@ -5314,6 +5355,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
@@ -5419,6 +5461,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5656,186 +5703,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Hjälp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>A&amp;vsluta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Paus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Sluta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Visa Statusfält</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
@@ -6135,27 +6212,27 @@ p, li { white-space: pre-wrap; }
<translation>Spelar inte något spel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Installerade SD-titlar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Installerade NAND-titlar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Systemtitlar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Lägg till ny spelkatalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoriter</translation>
</message>
@@ -6681,7 +6758,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Prokontroller</translation>
</message>
@@ -6694,7 +6771,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Dubbla Joycons</translation>
</message>
@@ -6707,7 +6784,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Vänster Joycon</translation>
</message>
@@ -6720,7 +6797,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Höger Joycon</translation>
</message>
@@ -6749,7 +6826,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handhållen</translation>
</message>
@@ -6865,32 +6942,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube-kontroll</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES-kontroll</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES-kontroll</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64-kontroll</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/tr_TR.ts b/dist/languages/tr_TR.ts
index 855540d30..4c7a85056 100644
--- a/dist/languages/tr_TR.ts
+++ b/dist/languages/tr_TR.ts
@@ -373,13 +373,13 @@ Bu işlem onların hem forum kullanıcı adını hem de IP adresini banlar.</tra
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation type="unfinished"/>
@@ -891,49 +891,29 @@ Bu işlem onların hem forum kullanıcı adını hem de IP adresini banlar.</tra
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Çöküş Sonrası Küçük Dump Oluştur</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Bu seçenek açıksa son oluşturulan ses komutları konsolda gösterilir. Sadece ses işleyicisi kullanan oyunları etkiler.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Konsola Ses Komutlarını Aktar**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Detaylı Raporlama Hizmetini Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Bu yuzu kapandığında otomatik olarak eski haline dönecektir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Yeniden Başlatma Gerekli</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu&apos;nun bu ayarı uygulayabilmesi için yeniden başlatılması gereklidir.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Web uygulaması derlenmemiş</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Küçük Dump oluşumu derlenmemiş</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1352,7 +1332,7 @@ Bu işlem onların hem forum kullanıcı adını hem de IP adresini banlar.</tra
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Tutarsız Anahtar Dizisi</translation>
</message>
@@ -1373,27 +1353,37 @@ Bu işlem onların hem forum kullanıcı adını hem de IP adresini banlar.</tra
<translation>Geçersiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Varsayılana Döndür</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Temizle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Tutarsız Tuş Dizisi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Varsayılan buton dizisi zaten %1&apos;e atanmış.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Varsayılan anahtar dizisi zaten %1&apos;e atanmış.</translation>
</message>
@@ -3370,67 +3360,72 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
<translation>Dosya Türü Sütununu Göster</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Oyun Simge Boyutu:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Dosya Simge Boyutu:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>1. Sıra Yazısı:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>2. Sıra Yazısı:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Ekran Görüntüleri</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Ekran Görüntülerinin Nereye Kaydedileceğini Belirle (Windows&apos;a Özel)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Ekran Görüntülerinin Konumu:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Çözünürlük:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Ekran Görüntülerinin Konumunu Seçin...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3748,612 +3743,616 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Yuzuyu geliştirmeye yardımcı olmak için &lt;/a&gt; anonim veri toplandı. &lt;br/&gt;&lt;br/&gt;Kullanım verinizi bizimle paylaşmak ister misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Bozuk Vulkan Kurulumu Algılandı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Açılışta Vulkan başlatılırken hata. Hata yardımını görüntülemek için &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;buraya tıklayın&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Web Uygulaması Yükleniyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Web Uygulamasını Devre Dışı Bırak</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Web uygulamasını kapatmak bilinmeyen hatalara neden olabileceğinden dolayı sadece Super Mario 3D All-Stars için kapatılması önerilir. Web uygulamasını kapatmak istediğinize emin misiniz?
(Hata ayıklama ayarlarından tekrar açılabilir)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Şu anda derlenen shader miktarı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Geçerli seçili çözünürlük ölçekleme çarpanı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Geçerli emülasyon hızı. %100&apos;den yüksek veya düşük değerler emülasyonun bir Switch&apos;den daha hızlı veya daha yavaş çalıştığını gösterir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Oyunun şuanda saniye başına kaç kare gösterdiği. Bu oyundan oyuna ve sahneden sahneye değişiklik gösterir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Bir Switch karesini emüle etmekte geçen zaman, karelimitleme ve v-sync hariç. Tam hız emülasyon için bu en çok 16,67 ms olmalı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Son Dosyaları Temizle</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Devam Et</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Duraklat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Uyarı, Eski Oyun Formatı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Bu oyun için dekonstrükte ROM formatı kullanıyorsunuz, bu fromatın yerine NCA, NAX, XCI ve NSP formatları kullanılmaktadır. Dekonstrükte ROM formatları ikon, üst veri ve güncelleme desteği içermemektedir.&lt;br&gt;&lt;br&gt;Yuzu&apos;nun desteklediği çeşitli Switch formatları için&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Wiki&apos;yi ziyaret edin&lt;/a&gt;. Bu mesaj yeniden gösterilmeyecektir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>ROM yüklenirken hata oluştu!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Bu ROM biçimi desteklenmiyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Video çekirdeğini başlatılırken bir hata oluştu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu video çekirdeğini çalıştırırken bir hatayla karşılaştı. Bu sorun genellikle eski GPU sürücüleri sebebiyle ortaya çıkar. Daha fazla detay için lütfen log dosyasına bakın. Log dosyasını incelemeye dair daha fazla bilgi için lütfen bu sayfaya ulaşın: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Log dosyası nasıl yüklenir&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROM yüklenirken hata oluştu! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Lütfen dosyalarınızı yeniden dump etmek için&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu hızlı başlangıç kılavuzu&apos;nu&lt;/a&gt; takip edin.&lt;br&gt; Yardım için yuzu wiki&lt;/a&gt;veya yuzu Discord&apos;una&lt;/a&gt; bakabilirsiniz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Bilinmeyen bir hata oluştu. Lütfen daha fazla detay için kütüğe göz atınız.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Yazılım kapatılıyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Kayıt Verisi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod Verisi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>%1 klasörü açılırken hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Klasör mevcut değil!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Transfer Edilebilir Shader Cache&apos;ini Açarken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Bu oyun için shader cache konumu oluşturulamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>İçerik Kaldırma Hatası</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Güncelleme Kaldırma hatası</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>DLC Kaldırma Hatası</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Yüklenmiş Oyun İçeriğini Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Yüklenmiş Oyun Güncellemesini Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Yüklenmiş DLC&apos;yi Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Girdiyi Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Başarıyla Kaldırıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Yüklenmiş oyun başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Asıl oyun NAND&apos;de kurulu değil ve kaldırılamaz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Yüklenmiş güncelleme başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Bu oyun için yüklenmiş bir güncelleme yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Bu oyun için yüklenmiş bir DLC yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 yüklenmiş DLC başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>OpenGL Transfer Edilebilir Shader Cache&apos;ini Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Vulkan Transfer Edilebilir Shader Cache&apos;ini Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Tüm Transfer Edilebilir Shader Cache&apos;leri Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Oyuna Özel Yapılandırmayı Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Dosyayı Sil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Transfer Edilebilir Shader Cache Kaldırılırken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Bu oyun için oluşturulmuş bir shader cache yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Transfer edilebilir shader cache başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Transfer edilebilir shader cache kaldırılamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Vulkan Pipeline Önbelleği Kaldırılırken Hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Sürücü pipeline önbelleği kaldırılamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Transfer Edilebilir Shader Cache&apos;ler Kaldırılırken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Transfer edilebilir shader cacheler başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Transfer edilebilir shader cache konumu kaldırılamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Oyuna Özel Yapılandırma Kaldırılırken Bir Hata Oluştu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Bu oyun için bir özel yapılandırma yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Oyuna özel yapılandırma başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Oyuna özel yapılandırma kaldırılamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS Çıkartımı Başarısız!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>RomFS dosyaları kopyalanırken bir hata oluştu veya kullanıcı işlemi iptal etti.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Full</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Çerçeve</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFS Dump Modunu Seçiniz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Lütfen RomFS&apos;in nasıl dump edilmesini istediğinizi seçin.&lt;br&gt;&quot;Full&quot; tüm dosyaları yeni bir klasöre kopyalarken &lt;br&gt;&quot;skeleton&quot; sadece klasör yapısını oluşturur.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 konumunda RomFS çıkarmaya yetecek alan yok. Lütfen yer açın ya da Emülasyon &gt; Yapılandırma &gt; Sistem &gt; Dosya Sistemi &gt; Dump konumu kısmından farklı bir çıktı konumu belirleyin.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>RomFS çıkartılıyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>İptal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS Çıkartımı Başarılı!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>İşlem başarıyla tamamlandı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Kısayol Oluştur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Bu seçenek, şu anki AppImage dosyasının kısayolunu oluşturacak. Uygulama güncellenirse kısayol çalışmayabilir. Devam edilsin mi?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Masaüstünde kısayol oluşturulamadı. &quot;%1&quot; dizini yok.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Uygulamalar menüsünde kısayol oluşturulamadı. &quot;%1&quot; dizini yok ve oluşturulamıyor.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Simge Oluştur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Simge dosyası oluşturulamadı. &quot;%1&quot; dizini yok ve oluşturulamıyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>yuzu Emülatörü başlatılırken %1 başlatılsın</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>%1 dizininde kısayol oluşturulamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>%1 dizinine kısayol oluşturuldu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>%1 Açılırken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Klasör Seç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Özellikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Oyun özellikleri yüklenemedi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Çalıştırılabilir Dosyası (%1);;Tüm Dosyalar (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Dosya Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Çıkartılmış ROM klasörünü aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Geçersiz Klasör Seçildi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Seçtiğiniz klasör bir &quot;main&quot; dosyası içermiyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Yüklenilebilir Switch Dosyası (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submissions Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Dosya Kur</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n dosya kaldı</numerusform><numerusform>%n dosya kaldı</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>&quot;%1&quot; dosyası kuruluyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Kurulum Sonuçları</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Olası çakışmaları önlemek için oyunları NAND&apos;e yüklememenizi tavsiye ediyoruz.
Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n dosya güncel olarak yüklendi
@@ -4361,7 +4360,7 @@ Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</tran
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n dosyanın üstüne yazıldı
@@ -4369,7 +4368,7 @@ Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</tran
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n dosya yüklenemedi
@@ -4377,339 +4376,371 @@ Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</tran
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Sistem Uygulaması</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Sistem Arşivi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Sistem Uygulama Güncellemesi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Yazılım Paketi (Tür A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Yazılım Paketi (Tür B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Oyun</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Oyun Güncellemesi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Oyun DLC&apos;si</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta Başlık</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>NCA Kurulum Tipi Seçin...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Lütfen bu NCA dosyası için belirlemek istediğiniz başlık türünü seçiniz:
(Çoğu durumda, varsayılan olan &apos;Oyun&apos; kullanılabilir.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Kurulum Başarısız Oldu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>NCA için seçtiğiniz başlık türü geçersiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Dosya Bulunamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Dosya &quot;%1&quot; Bulunamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>Tamam</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Donanım gereksinimleri karşılanmıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Sisteminiz, önerilen donanım gereksinimlerini karşılamıyor. Uyumluluk raporlayıcı kapatıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Kayıp yuzu Hesabı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Oyun uyumluluk test çalışması göndermek için öncelikle yuzu hesabınla giriş yapmanız gerekiyor.&lt;br&gt;&lt;br/&gt;Yuzu hesabınızla giriş yapmak için, Emülasyon &amp;gt; Yapılandırma &amp;gt; Web&apos;e gidiniz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>URL açılırken bir hata oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL &quot;%1&quot; açılamıyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS kayıtta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Oyuncu 1&apos;in dosyasının üstüne yazılsın mı?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Geçersiz yapılandırma tespit edildi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Handheld kontrolcü dock modunda kullanılamaz. Pro kontrolcü seçilecek.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Amiibo kaldırıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Aktif oyun amiibo beklemiyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo Dosyası (%1);; Tüm Dosyalar (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Amiibo Yükle</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Amiibo verisi yüklenirken hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Seçtiğiniz dosya geçerli bir amiibo değil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Seçtiğiniz dosya hali hazırda kullanılıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Bilinmeyen bir hata oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Ekran Görüntüsü Al</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG görüntüsü (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS durumu: %1%2 çalışıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS durumu: %1 kaydediliyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS durumu: %1%2 boşta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS durumu: Geçersiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Çalıştırmayı durdur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Başlat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>K&amp;aydetmeyi Durdur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>K&amp;aydet</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Oluşturuluyor: %n shader</numerusform><numerusform>Oluşturuluyor: %n shader</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Ölçek: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Hız %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Hız: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Oyun: %1 FPS (Sınırsız)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Oyun: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Kare: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>AA YOK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>SES: KAPALI</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>SES: %%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Anahtar Yeniden Türetimini Onayla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4726,37 +4757,37 @@ ve opsiyonel olarak yedekler alın.
Bu sizin otomatik oluşturulmuş anahtar dosyalarınızı silecek ve anahtar türetme modülünü tekrar çalıştıracak.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Anahtarlar Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- BOOT0 Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- BCPKG2-1-Normal-Main Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Türeten Bileşenleri Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Şifreleme anahtarları eksik. &lt;br&gt;Lütfen takip edin&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu hızlı başlangıç kılavuzunu&lt;/a&gt;tüm anahtarlarınızı, aygıt yazılımınızı ve oyunlarınızı almada.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4765,49 +4796,49 @@ Bu sistem performansınıza bağlı olarak
bir dakika kadar zaman alabilir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Anahtarlar Türetiliyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>RomFS Dump Hedefini Seçiniz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Lütfen dump etmek istediğiniz RomFS&apos;i seçiniz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>yuzu&apos;yu kapatmak istediğinizden emin misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Emülasyonu durdurmak istediğinizden emin misiniz? Kaydedilmemiş veriler kaybolur.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4959,241 +4990,251 @@ Görmezden gelip kapatmak ister misiniz?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Favori</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Oyunu Başlat</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Oyunu Özel Yapılandırma Olmadan Başlat</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Kayıt Dosyası Konumunu Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Mod Dosyası Konumunu Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Transfer Edilebilir Pipeline Cache&apos;ini Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Yüklenmiş Güncellemeleri Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Yüklenmiş DLC&apos;leri Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Oyuna Özel Yapılandırmayı Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>OpenGL Pipeline Cache&apos;ini Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Vulkan Pipeline Cache&apos;ini Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Bütün Pipeline Cache&apos;lerini Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Tüm Yüklenmiş İçeriği Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>RomFS Dump Et</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>RomFS&apos;i SDMC&apos;ye çıkar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Title ID&apos;yi Panoya Kopyala</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>GameDB sayfasına yönlendir</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Kısayol Oluştur</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Masaüstüne Ekle</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Uygulamalar Menüsüne Ekl</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Özellikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Alt Klasörleri Tara</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Oyun Konumunu Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲Yukarı Git</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼Aşağı Git</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Oyun Dosyası Konumunu Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Temizle</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>İsim</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Uyumluluk</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Eklentiler</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Dosya türü</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Boyut</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Oyunda</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Oyun başlatılabiliyor, fakat bariz hatalardan veya çökme sorunlarından dolayı bitirilemiyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Mükemmel</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Oyun sorunsuz bir şekilde oynanabiliyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Oynanabilir</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Oyun küçük grafik veya ses hatalarıyla çalışıyor ve baştan sona kadar oynanabilir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>İntro/Menü</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Oyun açılıyor, fakat ana menüden ileri gidilemiyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Açılmıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Oyun açılmaya çalışıldığında çöküyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Test Edilmedi</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Bu oyun henüz test edilmedi.</translation>
</message>
@@ -5201,7 +5242,7 @@ Görmezden gelip kapatmak ister misiniz?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Oyun listesine yeni bir klasör eklemek için çift tıklayın.</translation>
</message>
@@ -5214,12 +5255,12 @@ Görmezden gelip kapatmak ister misiniz?</translation>
<translation><numerusform>%n sonucun %1&apos;i</numerusform><numerusform>%n sonucun %1&apos;i</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Filtre:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Filtrelemek için bir düzen giriniz</translation>
</message>
@@ -5336,6 +5377,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Ana Pencere</translation>
</message>
@@ -5441,6 +5483,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Durum Çubuğunu Aç/Kapa</translation>
</message>
@@ -5679,186 +5726,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Yardım</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;NAND&apos;e Dosya Kur...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>&amp;Dosyayı Yükle...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>&amp;Klasörü Yükle...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>&amp;Çıkış</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Duraklat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>Du&amp;rdur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Anahtarları Yeniden Kur...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Yuzu Hakkında</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>&amp;Tek Pencere Modu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>&amp;Yapılandır...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>D&amp;ock Widget Başlıkları&apos;nı Göster</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>&amp;Filtre Çubuğu&apos;nu Göster</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>&amp;Durum Çubuğu&apos;nu Göster</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Durum Çubuğunu Göster</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Herkese Açık Oyun Lobilerine Göz At</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Oda Oluştur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Odadan Ayrıl</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Odaya Direkt Bağlan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Şu Anki Odayı Göster</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>&amp;Tam Ekran</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Yeniden Başlat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>&amp;Amiibo Yükle/Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Uyumluluk Bildir</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>&amp;Mod Sayfasını Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>&amp;Hızlı Başlangıç Kılavuzunu Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;SSS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>&amp;yuzu Klasörünü Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Ekran Görüntüsü Al</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;TAS&apos;i Ayarla...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>&amp;Geçerli Oyunu Yapılandır...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>B&amp;aşlat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Sıfırla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>K&amp;aydet</translation>
</message>
@@ -6166,27 +6243,27 @@ p, li { white-space: pre-wrap; }
<translation>Şu anda oyun oynamıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Yüklenmiş SD Oyunları</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Yüklenmiş NAND Oyunları</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Sistemde Yüklü Oyunlar</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Yeni Oyun Konumu Ekle</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Favoriler</translation>
</message>
@@ -6712,7 +6789,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6725,7 +6802,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>İkili Joyconlar</translation>
</message>
@@ -6738,7 +6815,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Sol Joycon</translation>
</message>
@@ -6751,7 +6828,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Sağ Joycon</translation>
</message>
@@ -6780,7 +6857,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
@@ -6896,32 +6973,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64 Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/uk.ts b/dist/languages/uk.ts
index 096c6039a..a4fb7893d 100644
--- a/dist/languages/uk.ts
+++ b/dist/languages/uk.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Авто (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>За замовчуванням (%1)</translation>
@@ -893,49 +893,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Створювати міні-дамп після крашу</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Увімкніть це щоб виводити останній згенерирований список аудіо команд в консоль. Впливає лише на ігри, які використовують аудіо рендерер.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Вивантажувати аудіо команди в консоль**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Увімкнути службу звітів у розгорнутому вигляді**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Це буде автоматично скинуто після закриття yuzu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Потрібен перезапуск</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu необхідно перезапустити, щоб застосувати це налаштування.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Веб-аплет не скомпільовано</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Створення міні-дампа не скомпільовано</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1354,7 +1334,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Конфліктуюча комбінація клавіш</translation>
</message>
@@ -1375,27 +1355,37 @@ This would ban both their forum username and their IP address.</source>
<translation>Неприпустимо</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Відновити значення за замовчуванням</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Очистити</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Конфліктуюче поєднання кнопок</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Типова комбінація кнопок вже призначена до: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Типова комбінація клавіш вже призначена до: %1</translation>
</message>
@@ -3373,67 +3363,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Показувати стовпець типу файлів</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Розмір іконки гри:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Розмір іконки папки:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Текст 1-го рядку:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Текст 2-го рядку:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Знімки екрану</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Запитувати куди зберігати знімки екрану (Тільки для Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Папка для знімків екрану:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Роздільна здатність:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Виберіть папку для знімків екрану...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation type="unfinished"/>
@@ -3751,612 +3746,616 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Анонімні дані збираються для того,&lt;/a&gt; щоб допомогти поліпшити роботу yuzu. &lt;br/&gt;&lt;br/&gt;Хотіли б ви ділитися даними про використання з нами?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Телеметрія</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Виявлено пошкоджену інсталяцію Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Не вдалося виконати ініціалізацію Vulkan під час завантаження.&lt;br&gt;&lt;br&gt;Натисніть &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;тут для отримання інструкцій щодо усунення проблеми&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Запущено гру</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Завантаження веб-аплета...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Вимкнути веб-аплет</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Вимкнення веб-апплета може призвести до несподіваної поведінки, і його слід вимикати лише заради Super Mario 3D All-Stars. Ви впевнені, що хочете вимкнути веб-апплет?
(Його можна знову ввімкнути в налаштуваннях налагодження.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Кількість створюваних шейдерів на цей момент</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Поточний обраний множник масштабування роздільної здатності.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Поточна швидкість емуляції. Значення вище або нижче 100% вказують на те, що емуляція йде швидше або повільніше, ніж на Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Кількість кадрів на секунду в цей момент. Значення буде змінюватися між іграми та сценами.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Час, який потрібен для емуляції 1 кадру Switch, не беручи до уваги обмеження FPS або вертикальну синхронізацію. Для емуляції в повній швидкості значення має бути не більше 16,67 мс.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Увімкнути звук</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Вимкнути звук</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Скинути гучність</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>[&amp;C] Очистити нещодавні файли</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Емульована мишка увімкнена</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Введення реальної миші та панорамування мишею несумісні. Будь ласка, вимкніть емульовану мишу в розширених налаштуваннях введення, щоб дозволити панорамування мишею.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>[&amp;C] Продовжити</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>[&amp;P] Пауза</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Попередження застарілий формат гри</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Для цієї гри ви використовуєте розархівований формат ROM&apos;а, який є застарілим і був замінений іншими, такими як NCA, NAX, XCI або NSP. У розархівованих каталогах ROM&apos;а відсутні іконки, метадані та підтримка оновлень. &lt;br&gt;&lt;br&gt;Для отримання інформації про різні формати Switch, підтримувані yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;перегляньте нашу вікі&lt;/a&gt;. Це повідомлення більше не буде відображатися.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Помилка під час завантаження ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Формат ROM&apos;а не підтримується.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Сталася помилка під час ініціалізації відеоядра.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu зіткнувся з помилкою під час запуску відеоядра. Зазвичай це спричинено застарілими драйверами ГП, включно з інтегрованими. Перевірте журнал для отримання більш детальної інформації. Додаткову інформацію про доступ до журналу дивіться на наступній сторінці: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Як завантажити файл журналу&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Помилка під час завантаження ROM&apos;а! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Будь ласка, дотримуйтесь &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;короткого керівництва користувача yuzu&lt;/a&gt; щоб пере-дампити ваші файли&lt;br&gt;Ви можете звернутися до вікі yuzu&lt;/a&gt; або Discord yuzu&lt;/a&gt; для допомоги</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Сталася невідома помилка. Будь ласка, перевірте журнал для подробиць.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-бітний)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-бітний)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Закриваємо програму...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Збереження</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Дані модів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Помилка під час відкриття папки %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Папка не існує!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Помилка під час відкриття переносного кешу шейдерів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Не вдалося створити папку кешу шейдерів для цієї гри.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Помилка під час видалення вмісту</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Помилка під час видалення оновлень</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Помилка під час видалення DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Видалити встановлений вміст ігор?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Видалити встановлені оновлення гри?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Видалити встановлені DLC гри?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Видалити запис</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Успішно видалено</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Встановлену гру успішно видалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Гру не встановлено в NAND і не може буде видалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Встановлене оновлення успішно видалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Для цієї гри не було встановлено оновлення.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Для цієї гри не було встановлено DLC.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Встановлений DLC %1 було успішно видалено</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Видалити переносний кеш шейдерів OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Видалити переносний кеш шейдерів Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Видалити весь переносний кеш шейдерів?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Видалити користувацьке налаштування гри?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Видалити кеш-сховище?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Видалити файл</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Помилка під час видалення переносного кешу шейдерів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Кеш шейдерів для цієї гри не існує.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Переносний кеш шейдерів успішно видалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Не вдалося видалити переносний кеш шейдерів.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Помилка під час видалення конвеєрного кешу Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Не вдалося видалити конвеєрний кеш шейдерів.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Помилка під час видалення переносного кешу шейдерів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Переносний кеш шейдерів успішно видалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Помилка під час видалення папки переносного кешу шейдерів.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Помилка під час видалення користувацького налаштування</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Користувацьких налаштувань для цієї гри не існує.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Користувацьке налаштування гри успішно видалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Не вдалося видалити користувацьке налаштування гри.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Не вдалося вилучити RomFS!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Сталася помилка під час копіювання файлів RomFS або користувач скасував операцію.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Повний</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Скелет</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Виберіть режим дампа RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Будь ласка, виберіть, як ви хочете виконати дамп RomFS &lt;br&gt;Повний скопіює всі файли в нову папку, тоді як &lt;br&gt;скелет створить лише структуру папок.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>В %1 недостатньо вільного місця для вилучення RomFS. Будь ласка, звільніть місце або виберіть іншу папку для дампа в Емуляція &gt; Налаштування &gt; Система &gt; Файлова система &gt; Корінь дампа</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Вилучення RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Скасувати</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Вилучення RomFS пройшло успішно!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Операція завершилася успішно.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Створити ярлик</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Це створить ярлик для поточного AppImage. Він може не працювати після оновлень. Продовжити?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Не вдається створити ярлик на робочому столі. Шлях &quot;%1&quot; не існує.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Неможливо створити ярлик у меню додатків. Шлях &quot;%1&quot; не існує і не може бути створений.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Створити іконку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Неможливо створити файл іконки. Шлях &quot;%1&quot; не існує і не може бути створений.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Запустити %1 за допомогою емулятора yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Не вдалося створити ярлик у %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Успішно створено ярлик у %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Помилка відкриття %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Обрати папку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Властивості</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Не вдалося завантажити властивості гри.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Виконуваний файл Switch (%1);;Усі файли (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Завантажити файл</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Відкрити папку вилученого ROM&apos;а</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Вибрано неприпустиму папку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Папка, яку ви вибрали, не містить файлу &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Встановлюваний файл Switch (*.nca, *.nsp, *.xci);;Архів контенту Nintendo (*.nca);;Пакет подачі Nintendo (*.nsp);;Образ картриджа NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Встановити файли</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>Залишився %n файл</numerusform><numerusform>Залишилося %n файл(ів)</numerusform><numerusform>Залишилося %n файл(ів)</numerusform><numerusform>Залишилося %n файл(ів)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Встановлення файлу &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Результати встановлення</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Щоб уникнути можливих конфліктів, ми не рекомендуємо користувачам встановлювати ігри в NAND.
Будь ласка, використовуйте цю функцію тільки для встановлення оновлень і завантажуваного контенту.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n файл було нещодавно встановлено
@@ -4366,7 +4365,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n файл було перезаписано
@@ -4376,7 +4375,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n файл не вдалося встановити
@@ -4386,339 +4385,371 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Системний додаток</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Системний архів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Оновлення системного додатку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Пакет прошивки (Тип А)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Пакет прошивки (Тип Б)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Гра</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Оновлення гри</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC до гри</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Дельта-титул</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Виберіть тип установки NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Будь ласка, виберіть тип додатку, який ви хочете встановити для цього NCA:
(У більшості випадків, підходить стандартний вибір &quot;Гра&quot;.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Помилка встановлення</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Тип додатку, який ви вибрали для NCA, недійсний.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Файл не знайдено</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Файл &quot;%1&quot; не знайдено</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>ОК</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Не задоволені системні вимоги</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Ваша система не відповідає рекомендованим системним вимогам. Звіти про сумісність було вимкнено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Відсутній обліковий запис yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Щоб надіслати звіт про сумісність гри, необхідно прив&apos;язати свій обліковий запис yuzu. &lt;br&gt;&lt;br/&gt;Щоб прив&apos;язати свій обліковий запис yuzu, перейдіть у розділ Емуляція &amp;gt; Параметри &amp;gt; Мережа.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Помилка під час відкриття URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Не вдалося відкрити URL: &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Запис TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Перезаписати файл гравця 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Виявлено неприпустиму конфігурацію</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Портативний контролер не може бути використаний у режимі док-станції. Буде обрано контролер Pro.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Поточний amiibo було прибрано</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Помилка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Поточна гра не шукає amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Файл Amiibo (%1);; Всі Файли (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Завантажити Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Помилка під час завантаження даних Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Обраний файл не є допустимим amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Обраний файл уже використовується</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Виникла невідома помилка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Зробити знімок екрану</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Зображення PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Стан TAS: Виконується %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Стан TAS: Записується %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Стан TAS: Простий %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Стан TAS: Неприпустимий</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>[&amp;S] Зупинка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>[&amp;S] Почати</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>[&amp;E] Закінчити запис</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>[&amp;E] Запис</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Побудова: %n шейдер</numerusform><numerusform>Побудова: %n шейдер(ів)</numerusform><numerusform>Побудова: %n шейдер(ів)</numerusform><numerusform>Побудова: %n шейдер(ів)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Масштаб: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Швидкість: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Швидкість: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Гра: %1 FPS (Необмежено)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Гра: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Кадр: %1 мс</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>БЕЗ ЗГЛАДЖУВАННЯ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>ГУЧНІСТЬ: ЗАГЛУШЕНА</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>ГУЧНІСТЬ: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Підтвердіть перерахунок ключа</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4735,37 +4766,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
Це видалить ваші автоматично згенеровані файли ключів і повторно запустить модуль розрахунку ключів.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Відсутні запобіжники</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- Відсутній BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Відсутній BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Відсутній PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Компоненти розрахунку відсутні</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Ключі шифрування відсутні.&lt;br&gt;Будь ласка, дотримуйтесь &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;короткого керівництва користувача yuzu&lt;/a&gt;, щоб отримати всі ваші ключі, прошивку та ігри&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4774,49 +4805,49 @@ on your system&apos;s performance.</source>
від продуктивності вашої системи.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Отримання ключів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Не вдалося розшифрувати системний архів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Ключі шифрування не змогли розшифрувати прошивку.&lt;br&gt;Будь ласка, дотримуйтесь &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;короткого керівництва користувача yuzu&lt;/a&gt; щоб отримати всі ваші ключі, прошивку та ігри.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Оберіть ціль для дампа RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Будь ласка, виберіть, який RomFS ви хочете здампити.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Ви впевнені, що хочете закрити yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Ви впевнені, що хочете зупинити емуляцію? Будь-який незбережений прогрес буде втрачено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4968,241 +4999,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Улюблені</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Запустити гру</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Запустити гру без користувацького налаштування</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Відкрити папку для збережень</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Відкрити папку для модів</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Відкрити переносний кеш конвеєра</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Видалити</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Видалити встановлене оновлення</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Видалити усі DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Видалити користувацьке налаштування</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Видалити кеш-сховище</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Видалити кеш конвеєра OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Видалити кеш конвеєра Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Видалити весь кеш конвеєра </translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Видалити весь встановлений вміст</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Дамп RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Здампити RomFS у SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Скопіювати ідентифікатор додатку в буфер обміну</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Перейти до сторінки GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Створити ярлик</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Додати на Робочий стіл</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Додати до меню застосунків</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Властивості</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Сканувати підпапки</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Видалити директорію гри</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Перемістити вверх</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Перемістити вниз</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Відкрити розташування папки</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Очистити</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Назва</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Сумісність</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Доповнення</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Тип файлу</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Розмір</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Запускається</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Гра запускається, але вильоти або серйозні баги не дають змоги її завершити.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Ідеально</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>У гру можна грати без проблем.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Придатно до гри</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Гра працює з незначними графічними та/або звуковими помилками і прохідна від початку до кінця.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Вступ/Меню</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Гра завантажується, але не проходить далі стартового екрана.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Не запускається</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Гра вилітає під час запуску.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Не перевірено</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Гру ще не перевіряли на сумісність.</translation>
</message>
@@ -5210,7 +5251,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Натисніть двічі, щоб додати нову папку до списку ігор</translation>
</message>
@@ -5223,12 +5264,12 @@ Would you like to bypass this and exit anyway?</source>
<translation><numerusform>%1 із %n результат(ів)</numerusform><numerusform>%1 із %n результат(ів)</numerusform><numerusform>%1 із %n результат(ів)</numerusform><numerusform>%1 із %n результат(ів)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Пошук:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Введіть текст для пошуку</translation>
</message>
@@ -5346,6 +5387,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Основне вікно</translation>
</message>
@@ -5451,6 +5493,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Переключити панель стану</translation>
</message>
@@ -5689,186 +5736,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>[&amp;T] TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>[&amp;H] Допомога</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>[&amp;I] Встановити файли в NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>[&amp;O] Завантажити файл...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>[&amp;F] Завантажити папку...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>[&amp;X] Вихід</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>[&amp;P] Пауза</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>[&amp;S] Стоп</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>[&amp;R] Переініціалізувати ключі...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>[&amp;A] Про yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>[&amp;W] Режим одного вікна</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>[&amp;F] Налаштування...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>[&amp;O] Відображати заголовки віджетів дока</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>[&amp;F] Показати панель пошуку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>[&amp;S] Показати панель статусу</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Показати панель статусу</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>[&amp;B] Переглянути публічні ігрові фойє</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>[&amp;C] Створити кімнату</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>[&amp;L] Залишити кімнату</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>[&amp;D] Пряме під&apos;єднання до кімнати</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>[&amp;S] Показати поточну кімнату</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>[&amp;U] Повноекранний</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>[&amp;R] Перезапустити</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>[&amp;A] Завантажити/Видалити Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>[&amp;R] Повідомити про сумісність</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>[&amp;M] Відкрити сторінку модів</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>[&amp;Q] Відкрити посібник користувача</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>[&amp;F] ЧАП</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>[&amp;Y] Відкрити папку yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>[&amp;C] Зробити знімок екрану</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>[&amp;C] Налаштування TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>[&amp;U] Налаштувати поточну гру...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>[&amp;S] Почати</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>[&amp;S] Скинути</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>[&amp;E] Запис</translation>
</message>
@@ -6176,27 +6253,27 @@ p, li { white-space: pre-wrap; }
<translation>Не грає в гру</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Встановлені SD ігри</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Встановлені NAND ігри</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Системні ігри</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Додати нову папку з іграми</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Улюблені</translation>
</message>
@@ -6722,7 +6799,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Контролер Pro</translation>
</message>
@@ -6735,7 +6812,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Подвійні Joy-Con&apos;и</translation>
</message>
@@ -6748,7 +6825,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Лівий Joy-Con</translation>
</message>
@@ -6761,7 +6838,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Правий Joy-Con</translation>
</message>
@@ -6790,7 +6867,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Портативний</translation>
</message>
@@ -6906,32 +6983,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Контролер GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Контролер NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Контролер SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Контролер N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/vi.ts b/dist/languages/vi.ts
index c4c1fb3b2..067aab070 100644
--- a/dist/languages/vi.ts
+++ b/dist/languages/vi.ts
@@ -373,13 +373,13 @@ Việc này sẽ ban tên người dùng trên diễn đàn và IP của họ lu
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Tự động (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Mặc định (%1)</translation>
@@ -893,49 +893,29 @@ Việc này sẽ ban tên người dùng trên diễn đàn và IP của họ lu
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Tạo Minidump sau khi crash</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Bật tính năng này để đưa ra danh sách lệnh âm thanh mới nhất đã tạo ra đến console. Chỉ ảnh hưởng đến các game sử dụng bộ mã hóa âm thanh.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Trích xuất các lệnh âm thanh đến console**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Bật dịch vụ báo cáo chi tiết**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Sẽ tự động đặt lại khi đóng yuzu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Cần khởi động lại</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu cần khởi động lại để áp dụng cài đặt này.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Applet web chưa được biên dịch</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Chức năng tạo MiniDump không được biên dịch</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1354,7 +1334,7 @@ Việc này sẽ ban tên người dùng trên diễn đàn và IP của họ lu
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Tổ hợp phím bị xung đột</translation>
</message>
@@ -1375,27 +1355,37 @@ Việc này sẽ ban tên người dùng trên diễn đàn và IP của họ lu
<translation>Không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Khôi phục mặc định</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Xóa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Tổ hợp nút bị xung đột</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Tổ hợp nút mặc định đã được gán cho: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Tổ hợp phím này đã gán với: %1</translation>
</message>
@@ -3373,67 +3363,72 @@ Kéo điểm để thay đổi vị trí, hoặc nhấp đúp chuột vào ô tr
<translation>Hiện cột Loại tập tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Kích thước biểu tượng game:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Kích thước biểu tượng thư mục:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Dòng chữ hàng 1:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Dòng chữ hàng 2:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Ảnh chụp màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Hỏi nơi lưu ảnh chụp màn hình (chỉ cho Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Đường dẫn cho ảnh chụp màn hình:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>NhãnVănBản</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Độ phân giải:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Chọn đường dẫn cho ảnh chụp màn hình...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Tự động (%1 x %2, %3 x %4)</translation>
@@ -3751,820 +3746,824 @@ Kéo điểm để thay đổi vị trí, hoặc nhấp đúp chuột vào ô tr
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dữ liệu ẩn danh được thu thập&lt;/a&gt;để hỗ trợ cải thiện yuzu. &lt;br/&gt;&lt;br/&gt;Bạn có muốn chia sẽ dữ liệu sử dụng với chúng tôi?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Viễn trắc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Phát hiện cài đặt Vulkan bị hỏng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Khởi tạo Vulkan thất bại trong quá trình khởi động.&lt;br&gt;Nhấp &lt;br&gt;&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;vào đây để xem hướng dẫn khắc phục vấn đề&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Đang chạy một game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Đang tải applet web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Tắt applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Tắt applet web có thể dẫn đến hành vi không xác định và chỉ nên được sử dụng với Super Mario 3D All-Stars. Bạn có chắc chắn muốn tắt applet web không?
(Có thể được bật lại trong cài đặt Gỡ lỗi.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Số lượng shader đang được dựng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Bội số tỷ lệ độ phân giải được chọn hiện tại.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Tốc độ giả lập hiện tại. Giá trị cao hơn hoặc thấp hơn 100% chỉ ra giả lập sẽ chạy nhanh hơn hoặc chậm hơn trên máy Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Có bao nhiêu khung hình trên mỗi giây mà game đang hiển thị. Điều này sẽ thay đổi giữa các game và các cảnh khác nhau.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Thời gian mà giả lập lấy từ khung hình Switch, sẽ không kể đến giới hạn khung hình hoặc v-sync. Đối với tốc độ tối đa mà giả lập nhận được nhiều nhất là ở độ khoảng 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Bật tiếng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Tắt tiếng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Đặt lại âm lượng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Xoá tập tin gần đây</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Chuột giả lập đã được bật</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Đầu vào từ chuột thật và tính năng lia chuột không tương thích. Vui lòng tắt chuột giả lập trong cài đặt đầu vào nâng cao để cho phép lia chuột.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Tiếp tục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Tạm dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Cảnh báo định dạng game đã lỗi thời</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Bạn đang sử dụng định dạng thư mục ROM đã giải nén cho game này, một định dạng lỗi thời đã được thay thế bởi những thứ khác như NCA, NAX, XCI, hoặc NSP. Thư mục ROM đã giải nén có thể thiếu các biểu tượng, metadata, và hỗ trợ cập nhật.&lt;br&gt;&lt;br&gt;Để hiểu thêm về các định dạng khác nhau của Switch mà yuzu hỗ trợ, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;vui lòng kiểm tra wiki của chúng tôi&lt;/a&gt;. Thông báo này sẽ không hiển thị lại lần sau.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Lỗi khi nạp ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Định dạng ROM này không được hỗ trợ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Đã xảy ra lỗi khi khởi tạo lõi video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu đã gặp lỗi khi chạy lõi video. Điều này thường xảy ra do phiên bản driver GPU đã cũ, bao gồm cả driver tích hợp. Vui lòng xem nhật ký để biết thêm chi tiết. Để biết thêm thông tin về cách truy cập nhật ký, vui lòng xem trang sau: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Cách tải lên tập tin nhật ký&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Lỗi khi nạp ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Vui lòng tuân theo &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;hướng dẫn nhanh của yuzu&lt;/a&gt; để trích xuất lại các tập tin của bạn.&lt;br&gt;Bạn có thể tham khảo yuzu wiki&lt;/a&gt; hoặc yuzu Discord&lt;/a&gt;để được hỗ trợ. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Đã xảy ra lỗi không xác định. Hãy xem nhật ký để biết thêm chi tiết.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Đang đóng phần mềm...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Dữ liệu save</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Dữ liệu mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Lỗi khi mở thư mục %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Thư mục này không tồn tại!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Lỗi khi mở bộ nhớ đệm shader chuyển được</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Thất bại khi tạo thư mục bộ nhớ đệm shader cho title này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Lỗi khi loại bỏ nội dung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Lỗi khi loại bỏ bản cập nhật</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Lỗi khi loại bỏ DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Loại bỏ nội dung game đã cài đặt?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Loại bỏ bản cập nhật game đã cài đặt?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Loại bỏ DLC game đã cài đặt?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Xoá mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Loại bỏ thành công</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Loại bỏ thành công base game đã cài đặt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Base game không được cài đặt trong NAND và không thể loại bỏ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Loại bỏ thành công bản cập nhật đã cài đặt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Không có bản cập nhật nào được cài đặt cho title này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Không có DLC nào được cài đặt cho title này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Loại bỏ thành công %1 DLC đã cài đặt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Xoá bộ nhớ đệm shader OpenGL chuyển được?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Xoá bộ nhớ đệm shader Vulkan chuyển được?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Xoá tất cả bộ nhớ đệm shader chuyển được?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Loại bỏ cấu hình game tuỳ chỉnh?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Loại bỏ bộ nhớ đệm?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Loại bỏ tập tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Lỗi khi loại bỏ bộ nhớ đệm shader chuyển được</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Bộ nhớ đệm shader cho title này không tồn tại.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Thành công loại bỏ bộ nhớ đệm shader chuyển được.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Thất bại khi xoá bộ nhớ đệm shader chuyển được.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Lỗi khi xoá bộ nhớ đệm pipeline Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Thất bại khi xoá bộ nhớ đệm pipeline của driver.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Lỗi khi loại bỏ bộ nhớ đệm shader chuyển được</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Thành công loại bỏ tất cả bộ nhớ đệm shader chuyển được.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Thất bại khi loại bỏ thư mục bộ nhớ đệm shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Lỗi khi loại bỏ cấu hình tuỳ chỉnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Cấu hình tuỳ chỉnh cho title này không tồn tại.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Loại bỏ thành công cấu hình game tuỳ chỉnh.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Thất bại khi xoá cấu hình game tuỳ chỉnh.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Giải nén RomFS không thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Đã xảy ra lỗi khi sao chép các tập tin RomFS hoặc người dùng đã hủy bỏ hoạt động này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Đầy đủ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Khung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Chọn chế độ trích xuất RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Vui lòng chọn cách mà bạn muốn RomFS được trích xuất.&lt;br&gt;Chế độ Đầy đủ sẽ sao chép toàn bộ tập tin vào một thư mục mới trong khi &lt;br&gt;chế độ Khung chỉ tạo cấu trúc thư mục.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Không đủ bộ nhớ trống tại %1 để trích xuất RomFS. Hãy giải phóng bộ nhớ hoặc chọn một thư mục trích xuất khác tại Giả lập &gt; Cấu hình &gt; Hệ thống &gt; Hệ thống tập tin &gt; Thư mục trích xuất gốc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Giải nén RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Hủy bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Giải nén RomFS thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Các hoạt động đã hoàn tất thành công.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>Không thể thực hiện kiểm tra tính toàn vẹn!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>Chưa kiểm tra sự hợp lệ của nội dung tập tin.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>Kiểm tra tính toàn vẹn thất bại!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>Nội dung tập tin có thể bị hỏng.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>Đang kiểm tra tính toàn vẹn...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>Kiểm tra tính toàn vẹn thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Tạo lối tắt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Việc này sẽ tạo một lối tắt tới AppImage hiện tại. Điều này có thể không hoạt động tốt nếu bạn cập nhật. Tiếp tục?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Không thể tạo lối tắt trên desktop. Đường dẫn &quot;%1&quot; không tồn tại.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Không thể tạo lối tắt trong menu ứng dụng. Đường dẫn &quot;%1&quot; không tồn tại và không thể tạo.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Tạo biểu tượng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Không thể tạo tập tin biểu tượng. Đường dẫn &quot;%1&quot; không tồn tại và không thể tạo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Bắt đầu %1 với giả lập yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Thất bại khi tạo lối tắt tại %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Thành công tạo lối tắt tại %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Lỗi khi mở %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Chọn thư mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Không thể tải thuộc tính của game.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Thực thi Switch (%1);;Tất cả tập tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Nạp tập tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Mở thư mục ROM đã giải nén</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Danh mục đã chọn không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Thư mục mà bạn đã chọn không chứa tập tin &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Những tập tin Switch cài được (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Cài đặt tập tin</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n tập tin còn lại</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Đang cài đặt tập tin &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Kết quả cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Để tránh xung đột có thể xảy ra, chúng tôi không khuyến khích người dùng cài đặt base game vào NAND.
Vui lòng, chỉ sử dụng tính năng này để cài đặt các bản cập nhật và DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n tập tin đã được cài đặt mới
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n tập tin đã được ghi đè
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n tập tin thất bại khi cài đặt
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Ứng dụng hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Bản lưu trữ của hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Cập nhật ứng dụng hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Gói firmware (Loại A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Gói firmware (Loại B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Cập nhật game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>DLC game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Title Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Chọn cách cài đặt NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vui lòng chọn loại title mà bạn muốn cài đặt NCA này:
(Trong hầu hết trường hợp, chọn mặc định &apos;Game&apos; là tốt nhất.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Cài đặt thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Loại title mà bạn đã chọn cho NCA không hợp lệ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Không tìm thấy tập tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Không tìm thấy tập tin &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Yêu cầu phần cứng không được đáp ứng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Hệ thống của bạn không đáp ứng yêu cầu phần cứng được đề xuất. Báo cáo độ tương thích đã bị vô hiệu hoá.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Thiếu tài khoản yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Để gửi trường hợp thử nghiệm game tương thích, bạn phải liên kết tài khoản yuzu.&lt;br&gt;&lt;br/&gt;Để liên kết tải khoản yuzu của bạn, hãy đến Giả lập &amp;gt; Cấu hình &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Lỗi khi mở URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Không thể mở URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Ghi lại TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Ghi đè tập tin của người chơi 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Đã phát hiện cấu hình không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Tay cầm handheld không thể được sử dụng trong chế độ docked. Pro Controller sẽ được chọn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Amiibo hiện tại đã được loại bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Lỗi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Game hiện tại không tìm kiếm amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Tập tin Amiibo (%1);; Tất cả tập tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Nạp Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Lỗi khi nạp dữ liệu Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Tập tin đã chọn không phải là amiibo hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Tập tin đã chọn đã được sử dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Đã xảy ra lỗi không xác định</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4573,145 +4572,177 @@ Vui lòng, chỉ sử dụng tính năng này để cài đặt các bản cập
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Hình ảnh PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Trạng thái TAS: Đang chạy %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Trạng thái TAS: Đang ghi %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Trạng thái TAS: Đang chờ %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Trạng thái TAS: Không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Dừng chạy</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Bắt đầu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Dừng G&amp;hi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>G&amp;hi</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Đang dựng: %n shader</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Tỉ lệ thu phóng: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Tốc độ: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Tốc độ: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Game: %1 FPS (Đã mở khoá)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Game: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Khung hình: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>ÂM LƯỢNG: TẮT TIẾNG</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>ÂM LƯỢNG: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Xác nhận chuyển hoá lại key</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4728,37 +4759,37 @@ và tạo một bản sao lưu.
Việc này sẽ xóa các tập tin key tự động sinh ra của bạn và chạy lại mô-đun chuyển hoá key.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Thiếu fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - Thiếu BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Thiếu BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Thiếu PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Thiếu các thành phần chuyển hoá</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Keys mã hoá bị thiếu. &lt;br&gt;Vui lòng tuân theo &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;hướng dẫn nhanh của yuzu&lt;/a&gt; để lấy tất cả key, firmware và game của bạn.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4767,49 +4798,49 @@ on your system&apos;s performance.</source>
hệ thống của bạn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Đang chuyển hoá key</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Giải mã bản lưu trữ của hệ thống thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Keys mã hoá thất bại khi giải mã firmware. &lt;br&gt;Vui lòng tuân theo &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;hướng dẫn nhanh của yuzu&lt;/a&gt;để lấy tất cả key, firmware và game của bạn. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Chọn thư mục để trích xuất RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vui lòng chọn RomFS mà bạn muốn trích xuất.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Bạn có chắc chắn muốn đóng yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Bạn có chắc rằng muốn dừng giả lập? Bất kì tiến trình nào chưa được lưu sẽ bị mất.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4961,241 +4992,251 @@ Bạn có muốn bỏ qua yêu cầu đó và thoát luôn không?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Ưa thích</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Bắt đầu game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Bắt đầu game mà không có cấu hình tuỳ chỉnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Mở vị trí dữ liệu save</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Mở vị trí chứa dữ liệu mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Mở thư mục chứa bộ nhớ đệm pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Loại bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Loại bỏ bản cập nhật đã cài</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Loại bỏ tất cả DLC đã cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Loại bỏ cấu hình tuỳ chỉnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Loại bỏ bộ nhớ đệm</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Loại bỏ bộ nhớ đệm pipeline OpenGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Loại bỏ bộ nhớ đệm pipeline Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Loại bỏ tất cả bộ nhớ đệm shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Loại bỏ tất cả nội dung đã cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Trích xuất RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Trích xuất RomFS tới SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Kiểm tra tính toàn vẹn</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Sao chép ID title vào bộ nhớ tạm</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Điều hướng đến mục GameDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Tạo lối tắt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Thêm vào desktop</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Thêm vào menu ứng dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Quét các thư mục con</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Loại bỏ thư mục game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Di chuyển lên</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Di chuyển xuống</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Mở vị trí thư mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Xóa</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Tên</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Độ tương thích</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Add-ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Loại tập tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Kích thước</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Trong game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Game khởi động, nhưng bị crash hoặc lỗi nghiêm trọng dẫn đến việc không thể hoàn thành nó.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Hoàn hảo</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Game có thể chơi mà không gặp vấn đề.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Có thể chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Game hoạt động với lỗi hình ảnh hoặc âm thanh nhẹ và có thể chơi từ đầu tới cuối.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Phần mở đầu/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Game đã tải, nhưng không thể qua được màn hình bắt đầu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Không khởi động</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Game crash khi đang khởi động.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Chưa ai thử</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Game này chưa được thử nghiệm.</translation>
</message>
@@ -5203,7 +5244,7 @@ Bạn có muốn bỏ qua yêu cầu đó và thoát luôn không?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Nhấp đúp chuột để thêm một thư mục mới vào danh sách game</translation>
</message>
@@ -5216,12 +5257,12 @@ Bạn có muốn bỏ qua yêu cầu đó và thoát luôn không?</translation>
<translation><numerusform>%1 trong %n kết quả</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Lọc:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Nhập mẫu để lọc</translation>
</message>
@@ -5339,6 +5380,7 @@ Tin nhắn gỡ lỗi:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Cửa sổ chính</translation>
</message>
@@ -5444,6 +5486,11 @@ Tin nhắn gỡ lỗi:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Hiện/Ẩn thanh trạng thái</translation>
</message>
@@ -5682,186 +5729,216 @@ Tin nhắn gỡ lỗi:</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Trợ giúp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Cài đặt tập tin vào NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>N&amp;ạp tập tin...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Nạp &amp;thư mục...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>T&amp;hoát</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Tạm dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Khởi tạo lại keys...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Thông tin về yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>Chế độ &amp;cửa sổ đơn</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Cấu &amp;hình...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Hiển thị tiêu đề công cụ D&amp;ock</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Hiện thanh &amp;lọc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Hiện thanh &amp;trạng thái</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Hiện thanh trạng thái</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Duyệt phòng game công khai</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Tạo phòng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Rời phòng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Kết nối trực tiếp tới phòng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Hiện phòng hiện tại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>T&amp;oàn màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Khởi động lại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Nạp/Loại bỏ &amp;Amiibo...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Báo cáo độ tương thích</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Mở trang &amp;mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Mở &amp;Hướng dẫn nhanh</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Mở thư mục &amp;yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Cấu hình TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Cấu hình game h&amp;iện tại...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Bắt đầu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Đặt lại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>G&amp;hi lại</translation>
</message>
@@ -6169,27 +6246,27 @@ p, li { white-space: pre-wrap; }
<translation>Hiện không chơi game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Các title đã cài đặt trên thẻ SD</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Các title đã cài đặt trên NAND</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Titles hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Thêm thư mục game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Ưa thích</translation>
</message>
@@ -6715,7 +6792,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6728,7 +6805,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Joycon đôi</translation>
</message>
@@ -6741,7 +6818,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon trái</translation>
</message>
@@ -6754,7 +6831,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon phải</translation>
</message>
@@ -6783,7 +6860,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
@@ -6899,32 +6976,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Tay cầm GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Tay cầm NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Tay cầm SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Tay cầm N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/vi_VN.ts b/dist/languages/vi_VN.ts
index fcc841ff2..2cee82e7e 100644
--- a/dist/languages/vi_VN.ts
+++ b/dist/languages/vi_VN.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>Tự động (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>Mặc định (%1)</translation>
@@ -893,49 +893,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>Tạo Minidump sau khi xảy ra sự cố.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Bật tính năng này để đưa ra danh sách lệnh âm thanh mới nhất đã tạo ra đến console. Chỉ ảnh hưởng đến các game sử dụng bộ mã hóa âm thanh.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>Trích xuất các lệnh âm thanh đến console**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>Bật dịch vụ báo cáo chi tiết**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Sẽ tự động thiết lập lại khi tắt yuzu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>Cần khởi động lại</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu cần khởi động lại để áp dụng cài đặt này.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Applet web chưa được biên dịch</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>Chức năng tạo MiniDump không được biên dịch</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1354,7 +1334,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>Tổ hợp phím bị xung đột</translation>
</message>
@@ -1375,27 +1355,37 @@ This would ban both their forum username and their IP address.</source>
<translation>Không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>Khôi phục về mặc định</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>Xóa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>Dãy nút xung đột</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>Dãy nút mặc định đã được gán cho: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>Tổ hợp phím này đã gán với: %1</translation>
</message>
@@ -3373,67 +3363,72 @@ Kéo điểm để thay đổi vị trí, hoặc nhấp đúp chuột vào ô tr
<translation>Hiện cột Loại tệp</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>Kích thước icon game:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>Kích thước icon thư mục:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>Dòng chữ hàng 1:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>Dòng chữ hàng 2:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>Ảnh chụp màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>Hỏi nơi lưu ảnh chụp màn hình (chỉ Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>Đường dẫn cho ảnh chụp màn hình:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>NhãnVănBản</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>Độ phân giải:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>Chọn đường dẫn cho ảnh chụp màn hình...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>Tự động (%1 x %2, %3 x %4)</translation>
@@ -3751,820 +3746,824 @@ Kéo điểm để thay đổi vị trí, hoặc nhấp đúp chuột vào ô tr
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dữ liệu ẩn danh được thu thập&lt;/a&gt;để hỗ trợ cải thiện yuzu. &lt;br/&gt;&lt;br/&gt;Bạn có muốn chia sẽ dữ liệu sử dụng cho chúng tôi?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>Viễn trắc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Phát hiện cài đặt Vulkan bị hỏng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Khởi tạo Vulkan thất bại trong quá trình khởi động.&lt;br&gt;Nhấn &lt;br&gt;&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;vào đây để xem hướng dẫn khắc phục vấn đề&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Đang chạy một game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>Đang tải applet web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>Tắt applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Tắt applet web có thể dẫn đến hành vi không xác định và chỉ nên được sử dụng với Super Mario 3D All-Stars. Bạn có chắc chắn muốn tắt applet web không?
(Có thể được bật lại trong cài đặt Gỡ lỗi.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>Số lượng shader đang được dựng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Bội số tỷ lệ độ phân giải được chọn hiện tại.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Tốc độ giả lập hiện tại. Giá trị cao hơn hoặc thấp hơn 100% chỉ ra giả lập sẽ chạy nhanh hơn hoặc chậm hơn trên máy Switch</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Có bao nhiêu khung hình trên mỗi giây mà trò chơi đang hiển thị. Điều này sẽ thay đổi từ trò chơi này đến trò chơi kia và khung cảnh này đến khung cảnh kia.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Thời gian mà giả lập lấy từ khung hình Switch, sẽ không kể đến giới hạn khung hình hoặc v-sync. Đối với tốc độ tối đa mà giả lập nhận được nhiều nhất là ở độ khoảng 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>Bật tiếng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>Tắt tiếng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>Đặt lại âm lượng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Xoá tập tin gần đây</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>Chuột giả lập đã được kích hoạt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>Đầu vào chuột thật và tính năng lia chuột không tương thích. Vui lòng tắt chuột giả lập trong cài đặt đầu vào nâng cao để cho phép lia chuột.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>&amp;Tiếp tục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;Tạm dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>Chú ý định dạng trò chơi đã lỗi thời</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Bạn đang sử dụng định dạng danh mục ROM giải mã cho trò chơi này, và đó là một định dạng lỗi thời đã được thay thế bởi những thứ khác như NCA, NAX, XCI, hoặc NSP. Danh mục ROM giải mã có thể thiếu biểu tượng, metadata, và hỗ trợ cập nhật.&lt;br&gt;&lt;br&gt;Để giải thích về các định dạng khác nhau của Switch mà yuzu hỗ trợ, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;vui lòng kiểm tra trên wiki của chúng tôi&lt;/a&gt;. Thông báo này sẽ không hiển thị lại lần sau.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>Xảy ra lỗi khi đang nạp ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>Định dạng ROM này không hỗ trợ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>Đã xảy ra lỗi khi khởi tạo lõi video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu đã gặp lỗi khi chạy lõi video. Điều này thường xảy ra do phiên bản driver GPU đã cũ, bao gồm cả driver tích hợp. Vui lòng xem nhật ký để biết thêm chi tiết. Để biết thêm thông tin về cách truy cập nhật ký, vui lòng xem trang sau: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Cách tải lên tập tin nhật ký&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Lỗi xảy ra khi nạp ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Vui lòng tuân theo &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;hướng dẫn nhanh của yuzu&lt;/a&gt; để trích xuất lại các tệp của bạn.&lt;br&gt;Bạn có thể tham khảo yuzu wiki&lt;/a&gt; hoặc yuzu Discord&lt;/a&gt;để được hỗ trợ. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Đã xảy ra lỗi không xác định. Vui lòng kiểm tra sổ ghi chép để biết thêm chi tiết.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>Đang đóng phần mềm...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>Dữ liệu save</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Dữ liệu mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>Xảy ra lỗi khi mở %1 thư mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>Thư mục này không tồn tại!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Lỗi khi mở bộ nhớ cache shader có thể chuyển.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Thất bại khi tạo thư mục bộ nhớ cache shader cho title này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>Lỗi khi loại bỏ nội dung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>Lỗi khi loại bỏ cập nhật</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>Lỗi khi loại bỏ DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>Loại bỏ nội dung game đã cài đặt?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>Loại bỏ bản cập nhật game đã cài đặt?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>Loại bỏ DLC game đã cài đặt?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>Xoá mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>Loại bỏ thành công</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>Loại bỏ thành công base game đã cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Base game không được cài đặt trong NAND và không thể loại bỏ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>Loại bỏ thành công bản cập nhật đã cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>Không có bản cập nhật nào được cài đặt cho title này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>Không có DLC nào được cài đặt cho title này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Loại bỏ thành công %1 DLC đã cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Xoá bộ nhớ cache shader OpenGL chuyển được?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Xoá bộ nhớ cache shader Vulkan chuyển được?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Xoá tất cả bộ nhớ cache shader chuyển được?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>Loại bỏ cấu hình game tuỳ chỉnh?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>Xoá bộ nhớ cache?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>Xoá tập tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Lỗi khi xoá bộ nhớ cache shader chuyển được</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>Bộ nhớ cache shader cho title này không tồn tại.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Thành công loại bỏ bộ nhớ cache shader chuyển được</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Thất bại khi xoá bộ nhớ cache shader chuyển được.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>Lỗi khi xoá bộ nhớ cache pipeline Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>Thất bại khi xoá bộ nhớ cache pipeline của driver.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Lỗi khi loại bỏ bộ nhớ cache shader chuyển được</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Thành công loại bỏ tât cả bộ nhớ cache shader chuyển được.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Thất bại khi loại bỏ thư mục bộ nhớ cache shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>Lỗi khi loại bỏ cấu hình tuỳ chỉnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Cấu hình tuỳ chỉnh cho title này không tồn tại.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Loại bỏ thành công cấu hình game tuỳ chỉnh.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Thất bại khi xoá cấu hình game tuỳ chỉnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>Khai thác RomFS không thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Đã xảy ra lỗi khi sao chép tệp tin RomFS hoặc người dùng đã hủy bỏ hoạt động này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>Đầy</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>Sườn</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>Chọn chế độ kết xuất RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Vui lòng chọn RomFS mà bạn muốn kết xuất như thế nào.&lt;br&gt;Đầy đủ sẽ sao chép toàn bộ tệp tin vào một danh mục mới trong khi &lt;br&gt;bộ xương chỉ tạo kết cấu danh mục.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Không đủ bộ nhớ trống tại %1 để trích xuất RomFS. Hãy giải phóng bộ nhớ hoặc chọn một thư mục trích xuất khác tại Giả lập &gt; Thiết lập &gt; Hệ thống &gt; Hệ thống tệp &gt; Thư mục trích xuất gốc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>Khai thác RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>Hủy bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Khai thác RomFS thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>Các hoạt động đã hoàn tất thành công.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>Không thể thực hiện kiểm tra tính toàn vẹn!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>Chưa kiểm tra sự hợp lệ của nội dung tập tin.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>Kiểm tra tính toàn vẹn thất bại!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>Nội dung tập tin có thể bị hỏng.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>Đang kiểm tra tính toàn vẹn...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>Kiểm tra tính toàn vẹn thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>Tạo lối tắt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>Việc này sẽ tạo một lối tắt tới AppImage hiện tại. Điều này có thể không hoạt động tốt nếu bạn cập nhật. Tiếp tục?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>Không thể tạo lối tắt trên desktop. Đường dẫn &quot;%1&quot; không tồn tại.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>Không thể tạo lối tắt trong menu ứng dụng. Đường dẫn &quot;%1&quot; không tồn tại và không thể tạo.</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>Tạo icon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>Không thể tạo tập tin icon. Đường dẫn &quot;%1&quot; không tồn tại và không thể tạo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>Bắt đầu %1 với giả lập yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>Thất bại khi tạo lối tắt tại %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>Thành công tạo lối tắt tại %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>Lỗi khi mở %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>Chọn danh mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>Thuộc tính của trò chơi không thể nạp được.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Thực thi Switch (%1);;Tất cả tệp tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>Nạp tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>Mở danh mục ROM đã trích xuất</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>Danh mục đã chọn không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Danh mục mà bạn đã chọn không có chứa tệp tin &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Những tệp tin Switch cài được (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>Cài đặt tập tin</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n tập tin còn lại</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Đang cài đặt tệp tin &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>Kết quả cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Để tránh xung đột có thể xảy ra, chúng tôi không khuyến khích người dùng cài base games vào NAND.
Vui lòng, chỉ sử dụng tính năng này để cài các bản cập nhật và DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n đã được cài đặt mới
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n tập tin đã được ghi đè
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n tập tin thất bại khi cài đặt
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>Ứng dụng hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>Hệ thống lưu trữ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>Cập nhật hệ thống ứng dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>Gói phần mềm (Loại A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>Gói phần mềm (Loại B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>Trò chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>Cập nhật trò chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>Nội dung trò chơi có thể tải xuống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Tiêu đề Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>Chọn loại NCA để cài đặt...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vui lòng chọn loại tiêu đề mà bạn muốn cài đặt NCA này:
(Trong hầu hết trường hợp, chọn mặc định &apos;Game&apos; là tốt nhất.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>Cài đặt đã không thành công</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Loại tiêu đề NCA mà bạn chọn nó không hợp lệ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>Không tìm thấy tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>Không tìm thấy &quot;%1&quot; tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>Yêu cầu phần cứng không được đáp ứng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>Hệ thống của bạn không đáp ứng yêu cầu phần cứng được đề xuất. Báo cáo tương thích đã được tắt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>Thiếu tài khoản yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Để gửi trường hợp thử nghiệm trò chơi tương thích, bạn phải liên kết tài khoản yuzu.&lt;br&gt;&lt;br/&gt;Để liên kết tải khoản yuzu của bạn, hãy đến Giả lập &amp;gt; Thiết lập &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>Lỗi khi mở URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Không thể mở URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>Ghi lại TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>Ghi đè tập tin của người chơi 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>Đã phát hiện cấu hình không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Tay cầm handheld không thể được sử dụng trong chế độ docked. Pro Controller sẽ được chọn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>Amiibo hiện tại đã bị loại bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>Lỗi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>Game hiện tại không tìm kiếm amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Tệp tin Amiibo (%1);; Tất cả tệp tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>Nạp dữ liệu Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>Xảy ra lỗi khi nạp dữ liệu Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>Tập tin đã chọn không phải là amiibo hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>Tập tin đã chọn đã được sử dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>Đã xảy ra lỗi không xác định</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4573,145 +4572,177 @@ Vui lòng, chỉ sử dụng tính năng này để cài các bản cập nhật
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>Hình ảnh PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>Trạng thái TAS: Đang chạy %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>Trạng thái TAS: Đang ghi %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>Trạng thái TAS: Đang chờ %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>Trạng thái TAS: Không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;Dừng chạy</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>&amp;Bắt đầu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>Dừng G&amp;hi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>G&amp;hi</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Đang dựng: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Tỉ lệ thu phóng: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>Tốc độ: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>Tốc độ: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Game: %1 FPS (Đã mở khoá)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>Trò chơi: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>Khung hình: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>ÂM LƯỢNG: TẮT TIẾNG</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>ÂM LƯỢNG: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>Xác nhận mã khóa Rederivation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4728,37 +4759,37 @@ và phải tạo ra một bản sao lưu lại.
Điều này sẽ xóa mã khóa tự động tạo trên tệp tin của bạn và chạy lại mô-đun mã khóa derivation.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>Thiếu fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation> - Thiếu BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Thiếu BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation> - Thiếu PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>Thiếu các thành phần chuyển hoá</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Keys mã hoá bị thiếu. &lt;br&gt;Vui lòng tuân theo &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;hướng dẫn nhanh của yuzu&lt;/a&gt; để lấy tất cả keys, firmware và games của bạn.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4767,49 +4798,49 @@ on your system&apos;s performance.</source>
vào hiệu suất hệ thống của bạn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>Mã khóa xuất phát</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>Giải mã bản lưu trữ của hệ thống thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>Keys mã hoá thấy bại khi giải mã firmware. &lt;br&gt;Vui lòng tuân theo &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;hướng dẫn nhanh của yuzu&lt;/a&gt;để lấy tất cả keys, firmware và games của bạn. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>Chọn thư mục để sao chép RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vui lòng chọn RomFS mà bạn muốn sao chép.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Bạn có chắc chắn muốn đóng yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Bạn có chắc rằng muốn dừng giả lập? Bất kì tiến trình nào chưa được lưu sẽ bị mất.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4961,241 +4992,251 @@ Bạn có muốn bỏ qua yêu cầu đó và thoát luôn không?</translation>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>Ưa thích</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>Bắt đầu game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>Bắt đầu game mà không có cấu hình tuỳ chỉnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>Mở vị trí lưu dữ liệu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>Mở vị trí chỉnh sửa dữ liệu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>Mở thư mục chứa bộ nhớ cache pipeline</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>Gỡ Bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>Loại bỏ bản cập nhật đã cài</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>Loại bỏ tất cả DLC đã cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>Loại bỏ cấu hình tuỳ chỉnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>Xoá bộ nhớ cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>Loại bỏ OpenGL Pipeline Cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>Loại bỏ bộ nhớ cache pipeline Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>Loại bỏ tất cả bộ nhớ cache shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>Loại bỏ tất cả nội dung đã cài đặt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>Kết xuất RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>Trích xuất RomFS tới SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>Kiểm tra tính toàn vẹn</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>Sao chép ID tiêu đề vào bộ nhớ tạm</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>Điều hướng đến mục cơ sở dữ liệu trò chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>Tạo lối tắt</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>Thêm vào Desktop</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>Thêm vào menu ứng dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>Quét các thư mục con</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>Loại bỏ thư mục game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ Di chuyển lên</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ Di chuyển xuống</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>Mở vị trí thư mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>Bỏ trống</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>Tên</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>Tương thích</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>Tiện ích ngoài</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>Loại tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>Kích cỡ</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>Trong game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>Game khởi động, nhưng gặp vấn đề hoặc lỗi nghiêm trọng đến việc không thể hoàn thành trò chơi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>Tốt nhất</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>Game có thể chơi mà không gặp vấn đề.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>Có thể chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>Game hoạt động với lỗi hình ảnh hoặc âm thanh nhẹ và có thể chơi từ đầu tới cuối.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>Phần mở đầu/Menu</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>Trò chơi đã tải, nhưng không thể qua Màn hình Bắt đầu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>Không hoạt động</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>Trò chơi sẽ thoát đột ngột khi khởi động.</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>Chưa ai thử</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>Trò chơi này chưa có ai thử cả.</translation>
</message>
@@ -5203,7 +5244,7 @@ Bạn có muốn bỏ qua yêu cầu đó và thoát luôn không?</translation>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>Nháy đúp chuột để thêm một thư mục mới vào danh sách trò chơi game</translation>
</message>
@@ -5216,12 +5257,12 @@ Bạn có muốn bỏ qua yêu cầu đó và thoát luôn không?</translation>
<translation><numerusform>%1 trong %n kết quả</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>Bộ lọc:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>Nhập khuôn để lọc</translation>
</message>
@@ -5339,6 +5380,7 @@ Tin nhắn gỡ lỗi:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>Cửa sổ chính</translation>
</message>
@@ -5444,6 +5486,11 @@ Tin nhắn gỡ lỗi:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>Hiện/Ẩn thanh trạng thái</translation>
</message>
@@ -5682,186 +5729,216 @@ Tin nhắn gỡ lỗi:</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>&amp;TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>&amp;Trợ giúp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;Cài đặt tập tin vào NAND...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>N&amp;ạp tập tin...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>Nạp &amp;Thư mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>Th&amp;oát</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>&amp;Tạm dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>&amp;Dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>&amp;Khởi tạo lại keys...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>&amp;Thông tin về yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>&amp;Chế độ cửa sổ đơn</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>Cấu&amp; hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>Hiển thị tiêu đề công cụ D&amp;ock</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>Hiện thanh &amp;lọc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>Hiện thanh &amp;trạng thái</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>Hiển thị thanh trạng thái</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>&amp;Duyệt phòng game công khai</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>&amp;Tạo phòng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>&amp;Rời phòng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>&amp;Kết nối trực tiếp tới phòng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>&amp;Hiện phòng hiện tại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>T&amp;oàn màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>&amp;Khởi động lại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>Tải/Loại bỏ &amp;Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>&amp;Báo cáo tương thích</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>Mở trang &amp;mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>Mở &amp;Hướng dẫn nhanh</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>&amp;FAQ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>Mở thư mục &amp;yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>&amp;Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>&amp;Cấu hình TAS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>Cấu hình game hiện tại...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>&amp;Bắt đầu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>&amp;Đặt lại</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>G&amp;hi</translation>
</message>
@@ -6168,27 +6245,27 @@ p, li { white-space: pre-wrap; }
<translation>Hiện không chơi game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>Các title đã cài đặt trên thẻ SD</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>Các title đã cài đặt trên NAND</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>Titles hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>Thêm thư mục game</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>Ưa thích</translation>
</message>
@@ -6714,7 +6791,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Tay cầm Pro Controller</translation>
</message>
@@ -6727,7 +6804,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>Joycon đôi</translation>
</message>
@@ -6740,7 +6817,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>Joycon Trái</translation>
</message>
@@ -6753,7 +6830,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>Joycon Phải</translation>
</message>
@@ -6782,7 +6859,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>Cầm tay</translation>
</message>
@@ -6898,32 +6975,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>Tay cầm GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>Tay cầm NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>Tay cầm SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>Tay cầm N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
diff --git a/dist/languages/zh_CN.ts b/dist/languages/zh_CN.ts
index 65baa9175..b7f1d32fb 100644
--- a/dist/languages/zh_CN.ts
+++ b/dist/languages/zh_CN.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>自动 (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>默认 (%1)</translation>
@@ -853,7 +853,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="403"/>
<source>Disable Web Applet</source>
- <translation>禁用 Web 应用程序</translation>
+ <translation>禁用 Web 小程序</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="410"/>
@@ -892,48 +892,28 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>微型故障转储</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>启用此选项会将最新的音频命令列表输出到控制台。只影响使用音频渲染器的游戏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>将音频命令转储至控制台**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>启用详细报告服务**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**该选项将在 yuzu 关闭时自动重置。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>需要重启</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>重启 yuzu 后才能应用此设置。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
- <translation>Web 应用程序未编译</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>微型转储未编译</translation>
+ <translation>Web 小程序未编译</translation>
</message>
</context>
<context>
@@ -1353,7 +1333,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>按键冲突</translation>
</message>
@@ -1374,27 +1354,37 @@ This would ban both their forum username and their IP address.</source>
<translation>无效</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>无效的热键设置</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation>发生错误。请在 GitHub 提交 Issue。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>恢复默认</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>清除</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>键位冲突</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>默认的按键序列已分配给: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>默认的按键序列已分配给: %1</translation>
</message>
@@ -1720,7 +1710,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2668"/>
<source>Enable XInput 8 player support (disables web applet)</source>
- <translation>启用 XInput 8 输入支持 (禁用 web 应用程序)</translation>
+ <translation>启用 XInput 8 输入支持 (禁用 web 小程序)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2681"/>
@@ -3372,67 +3362,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>显示“文件类型”列</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>显示“游玩时间”列</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>游戏图标大小:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>文件夹图标大小:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>第一行:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>第二行:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>捕获截图</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>询问保存截图的位置 (仅限 Windows )</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>截图保存位置:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>文本水印</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>分辨率:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>选择截图保存位置...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>自动 (%1 x %2, %3 x %4)</translation>
@@ -3750,820 +3745,824 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;我们收集匿名数据&lt;/a&gt;来帮助改进 yuzu 。&lt;br/&gt;&lt;br/&gt;您愿意和我们分享您的使用数据吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>使用数据共享</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>检测到 Vulkan 的安装已损坏</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Vulkan 初始化失败。&lt;br&gt;&lt;br&gt;点击&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;这里&lt;/a&gt;获取此问题的相关信息。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>游戏正在运行</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
- <translation>正在加载 Web 应用程序...</translation>
+ <translation>正在加载 Web 小程序...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
- <translation>禁用 Web 应用程序</translation>
+ <translation>禁用 Web 小程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
- <translation>禁用 Web 应用程序可能会发生未知的行为,且只能在《超级马里奥 3D 全明星》中使用。您确定要禁用 Web 应用程序吗?
+ <translation>禁用 Web 小程序可能会发生未知的行为,且只能在《超级马里奥 3D 全明星》中使用。您确定要禁用 Web 小程序吗?
(您可以在调试选项中重新启用它。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>当前正在构建的着色器数量</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>当前选定的分辨率缩放比例。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>当前的模拟速度。高于或低于 100% 的值表示运行速度比实际的 Switch 更快或更慢。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>游戏当前运行的帧率。这将因游戏和场景的不同而有所变化。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>在不计算速度限制和垂直同步的情况下,模拟一个 Switch 帧的实际时间。若要进行全速模拟,这个数值不应超过 16.67 毫秒。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>取消静音</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>静音</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>重置音量</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>清除最近文件 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>已启用模拟鼠标</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>实体鼠标输入与鼠标平移不兼容。请在高级输入设置中禁用模拟鼠标以使用鼠标平移。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>继续 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>暂停 (&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>过时游戏格式警告</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>目前使用的游戏为解体的 ROM 目录格式,这是一种过时的格式,已被其他格式替代,如 NCA,NAX,XCI 或 NSP。解体的 ROM 目录缺少图标、元数据和更新支持。&lt;br&gt;&lt;br&gt;有关 yuzu 支持的各种 Switch 格式的说明,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;请查看我们的 wiki&lt;/a&gt;。此消息将不会再次出现。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>加载 ROM 时出错!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>该 ROM 格式不受支持。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>初始化视频核心时发生错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu 在运行视频核心时发生错误。这可能是由 GPU 驱动程序过旧造成的。有关详细信息,请参阅日志文件。关于日志文件的更多信息,请参考以下页面:&lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;如何上传日志文件&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>加载 ROM 时出错! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;请参考&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速导航&lt;/a&gt;以获取相关文件。&lt;br&gt;您可以参考 yuzu 的 wiki 页面&lt;/a&gt;或 Discord 社区&lt;/a&gt;以获得帮助。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>发生了未知错误。请查看日志了解详情。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>正在关闭…</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>保存数据</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>Mod 数据</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>打开 %1 文件夹时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>文件夹不存在!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>打开可转移着色器缓存时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>为该游戏创建着色器缓存目录时失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>删除内容时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>删除更新时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>删除 DLC 时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>删除已安装的游戏内容?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>删除已安装的游戏更新?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>删除已安装的游戏 DLC 内容?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>删除项目</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>删除成功</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>成功删除已安装的游戏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>该游戏未安装于 NAND 中,无法删除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>成功删除已安装的游戏更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>这个游戏没有任何已安装的更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>这个游戏没有任何已安装的 DLC 。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>成功删除游戏 %1 安装的 DLC 。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>删除 OpenGL 模式的着色器缓存?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>删除 Vulkan 模式的着色器缓存?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>删除所有的着色器缓存?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>移除自定义游戏设置?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>移除缓存?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>删除文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>清除游玩时间</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>重置游玩时间?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>删除着色器缓存时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>这个游戏的着色器缓存不存在。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>成功删除着色器缓存。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>删除着色器缓存失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>删除 Vulkan 驱动程序管线缓存时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>删除驱动程序管线缓存失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>删除着色器缓存时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>着色器缓存删除成功。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>删除着色器缓存目录失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>移除自定义游戏设置时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>这个游戏的自定义设置不存在。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>成功移除自定义游戏设置。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>移除自定义游戏设置失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS 提取失败!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>复制 RomFS 文件时出错,或用户取消了操作。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>完整</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>框架</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>选择 RomFS 转储模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>请选择 RomFS 转储的方式。&lt;br&gt;“完整” 会将所有文件复制到新目录中,而&lt;br&gt;“框架” 只会创建目录结构。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 没有足够的空间用于提取 RomFS。请保持足够的空间或于模拟—&gt;设置—&gt;系统—&gt;文件系统—&gt;转储根目录中选择一个其他目录。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>正在提取 RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>取消</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS 提取成功!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>操作成功完成。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>无法执行完整性验证!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>未检查文件的完整性。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>完整性验证失败!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>文件可能已经损坏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>正在验证完整性...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>完整性验证成功!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>创建快捷方式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>这将为当前的游戏创建快捷方式。但在其更新后,快捷方式可能无法正常工作。是否继续?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>无法在桌面创建快捷方式。路径“ %1 ”不存在。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>无法在应用程序菜单中创建快捷方式。路径“ %1 ”不存在且无法被创建。</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>无法创建快捷方式。路径“ %1 ”不存在。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>创建图标</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>无法创建图标文件。路径“ %1 ”不存在且无法被创建。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>使用 yuzu 启动 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>在 %1 处创建快捷方式时失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>成功地在 %1 处创建快捷方式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>打开 %1 时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>选择目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>属性</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>无法加载该游戏的属性信息。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch 可执行文件 (%1);;所有文件 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>加载文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>打开提取的 ROM 目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>选择的目录无效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>选择的目录不包含 “main” 文件。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>可安装 Switch 文件 (*.nca *.nsp *.xci);;任天堂内容档案 (*.nca);;任天堂应用包 (*.nsp);;NX 卡带镜像 (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>安装文件</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>剩余 %n 个文件</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>正在安装文件 &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>安装结果</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>为了避免可能存在的冲突,我们不建议将游戏本体安装到 NAND 中。
此功能仅用于安装游戏更新和 DLC 。</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>最近安装了 %n 个文件
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n 个文件被覆盖
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n 个文件安装失败
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>系统应用</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>系统档案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>系统应用更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>固件包 (A型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>固件包 (B型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>游戏更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>游戏 DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>差量程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>选择 NCA 安装类型...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>请选择此 NCA 的程序类型:
(在大多数情况下,选择默认的“游戏”即可。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>安装失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>选择的 NCA 程序类型无效。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>找不到文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>文件 &quot;%1&quot; 未找到</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>确定</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>硬件不满足要求</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>您的系统不满足运行 yuzu 的推荐配置。兼容性报告已被禁用。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>未设置 yuzu 账户</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>要提交游戏兼容性测试用例,您必须设置您的 yuzu 帐户。&lt;br&gt;&lt;br/&gt;要设置您的 yuzu 帐户,请转到模拟 &amp;gt; 设置 &amp;gt; 网络。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>打开 URL 时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>无法打开 URL : &quot;%1&quot; 。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS 录制中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>覆盖玩家 1 的文件?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>检测到无效配置</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>掌机手柄无法在主机模式中使用。将会选择 Pro controller。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>当前的 Amiibo 已被移除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>当前游戏并没有在寻找 Amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo 文件 (%1);; 全部文件 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>加载 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>加载 Amiibo 数据时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>选择的文件并不是有效的 amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>选择的文件已在使用中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>发生了未知错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4572,145 +4571,177 @@ Please, only use this feature to install updates and DLC.</source>
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation>无可用固件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>请安装固件以使用相册小程序。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>相册小程序</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>相册小程序不可用。请重新安装固件。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>请安装固件以使用 Cabinet 小程序。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Cabinet 小程序</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>Cabinet 小程序不可用。请重新安装固件。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation>请安装固件以使用 Mii editor。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
- <translation>MiiEdit 小程序</translation>
+ <translation>Mii Edit 小程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
- <translation>Mii editor 不可用。请安装固件。</translation>
+ <translation>Mii editor 不可用。请重新安装固件。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>捕获截图</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG 图像 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 状态:正在运行 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS 状态:正在录制 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 状态:空闲 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS 状态:无效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>停止运行 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>开始 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>停止录制 (&amp;E)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>录制 (&amp;E)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>正在编译 %n 个着色器文件</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>缩放比例: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>速度: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>速度: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>FPS: %1 (未锁定)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>FPS: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>帧延迟: %1 毫秒</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>抗锯齿关</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>音量: 静音</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>音量: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>确认重新生成密钥</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4726,37 +4757,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
这将删除您自动生成的密钥文件并重新运行密钥生成模块。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>项目丢失</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- 丢失 BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - 丢失 BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- 丢失 PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>组件丢失</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>密钥缺失。&lt;br&gt;请查看&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速导航&lt;/a&gt;以获得你的密钥、固件和游戏。&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4765,49 +4796,49 @@ on your system&apos;s performance.</source>
您的系统性能。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>生成密钥</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>系统固件解密失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>当前密钥无法解密系统固件。&lt;br&gt;请查看&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速导航&lt;/a&gt;以获得你的密钥、固件和游戏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>选择 RomFS 转储目标</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>请选择希望转储的 RomFS。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>您确定要关闭 yuzu 吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>您确定要停止模拟吗?未保存的进度将会丢失。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4959,241 +4990,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>收藏</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>开始游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>使用公共设置项进行游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>打开存档位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>打开 MOD 数据位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>打开可转移着色器缓存</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>删除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>删除已安装的游戏更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>删除所有已安装 DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>删除自定义设置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>清除游玩时间</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>移除缓存</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>删除 OpenGL 着色器缓存</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>删除 Vulkan 着色器缓存</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>删除所有着色器缓存</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>删除所有安装的项目</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>转储 RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>转储 RomFS 到 SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>完整性验证</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>复制游戏 ID 到剪贴板</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>查看兼容性报告</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>创建快捷方式</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>添加到桌面</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>添加到应用程序菜单</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>属性</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>扫描子文件夹</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>移除游戏目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ 向上移动</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ 向下移动</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>打开目录位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>清除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>名称</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>兼容性</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>附加项</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>文件类型</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>大小</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>游玩时间</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>可进游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>游戏可以开始,但会出现崩溃或严重故障导致游戏无法继续。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>完美</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>游戏可以毫无问题地运行。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>可运行</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>游戏可以从头到尾完整地运行,但可能出现轻微的图形或音频故障。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>开场/菜单</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>游戏可以加载,但无法通过标题页面。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>无法启动</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>在启动游戏时直接崩溃。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>未测试</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>游戏尚未经过测试。</translation>
</message>
@@ -5201,7 +5242,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>双击添加新的游戏文件夹</translation>
</message>
@@ -5214,12 +5255,12 @@ Would you like to bypass this and exit anyway?</source>
<translation><numerusform>%1 / %n 个结果</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>搜索:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>搜索游戏</translation>
</message>
@@ -5337,6 +5378,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>主窗口</translation>
</message>
@@ -5442,6 +5484,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation>切换到 Renderdoc 捕获截图</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>切换状态栏</translation>
</message>
@@ -5680,186 +5727,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>Amiibo (&amp;A)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>TAS (&amp;T)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>帮助 (&amp;H)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>安装文件到 NAND... (&amp;I)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>加载文件... (&amp;O)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>加载文件夹... (&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>退出 (&amp;X)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>暂停 (&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>停止 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>重新生成密钥... (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation>验证已安装内容的完整性 (&amp;V)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>关于 yuzu (&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>单窗口模式 (&amp;W)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>设置... (&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>显示停靠小部件的标题 (&amp;O)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>显示搜索栏 (&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>显示状态栏 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>显示状态栏</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>浏览公共游戏大厅 (&amp;B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>创建房间 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>离开房间 (&amp;L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>直接连接到房间 (&amp;D)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>显示当前房间 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>全屏 (&amp;U)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>重新启动 (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>加载/移除 Amiibo... (&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>报告兼容性 (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>打开 Mod 页面 (&amp;M)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>查看快速导航 (&amp;Q)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>FAQ (&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>打开 yuzu 文件夹 (&amp;Y)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>捕获截图 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>打开相册 (&amp;A)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>设置昵称及所有者 (&amp;S)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>删除游戏数据 (&amp;D)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>重置 Amiibo (&amp;R)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>格式化 Amiibo (&amp;F)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation>打开 Mii Editor (&amp;M)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>配置 TAS... (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>配置当前游戏... (&amp;U)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>开始 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>重置 (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>录制 (&amp;E)</translation>
</message>
@@ -6167,27 +6244,27 @@ p, li { white-space: pre-wrap; }
<translation>不在玩游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>SD 卡中安装的项目</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>NAND 中安装的项目</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>系统项目</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>添加游戏目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>收藏</translation>
</message>
@@ -6682,7 +6759,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="14"/>
<source>Controller Applet</source>
- <translation>控制器程序</translation>
+ <translation>控制器小程序</translation>
</message>
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="129"/>
@@ -6713,7 +6790,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
@@ -6726,7 +6803,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>双 Joycons 手柄</translation>
</message>
@@ -6739,7 +6816,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>左 Joycon 手柄</translation>
</message>
@@ -6752,7 +6829,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>右 Joycon 手柄</translation>
</message>
@@ -6781,7 +6858,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>掌机模式</translation>
</message>
@@ -6897,32 +6974,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>控制器数量不足</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>精灵球 PLUS</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>世嘉创世纪</translation>
</message>
diff --git a/dist/languages/zh_TW.ts b/dist/languages/zh_TW.ts
index 52421f6f6..f0cc66e0a 100644
--- a/dist/languages/zh_TW.ts
+++ b/dist/languages/zh_TW.ts
@@ -373,13 +373,13 @@ This would ban both their forum username and their IP address.</source>
<translation>%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="319"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="321"/>
<source>Auto (%1)</source>
<comment>Auto select time zone</comment>
<translation>自動 (%1)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="323"/>
+ <location filename="../../src/yuzu/configuration/shared_translation.cpp" line="325"/>
<source>Default (%1)</source>
<comment>Default time zone</comment>
<translation>預設 (%1)</translation>
@@ -892,49 +892,29 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="477"/>
- <source>Create Minidump After Crash</source>
- <translation>微型故障转储</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="484"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>启用此选项会将最新的音频命令列表输出到控制台。只影响使用音频渲染器的游戏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="480"/>
<source>Dump Audio Commands To Console**</source>
<translation>将音频命令转储至控制台**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="494"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="487"/>
<source>Enable Verbose Reporting Services**</source>
<translation>啟用詳細報告服務</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="546"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="539"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**當 yuzu 關閉時會自動重設。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
- <source>Restart Required</source>
- <translation>需要重新啟動</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
- <source>yuzu is required to restart in order to apply this setting.</source>
- <translation>yuzu 需要重新啟動以套用此設定。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="80"/>
<source>Web applet not compiled</source>
<translation>Web 小程式未編譯</translation>
</message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="97"/>
- <source>MiniDump creation not compiled</source>
- <translation>小型转储创建未编译</translation>
- </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1353,7 +1333,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="140"/>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="168"/>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="394"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="401"/>
<source>Conflicting Key Sequence</source>
<translation>按鍵衝突</translation>
</message>
@@ -1374,27 +1354,37 @@ This would ban both their forum username and their IP address.</source>
<translation>無效</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="358"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="325"/>
+ <source>Invalid hotkey settings</source>
+ <translation>无效的热键设置</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="326"/>
+ <source>An error occurred. Please report this issue on github.</source>
+ <translation>发生错误。请在 GitHub 提交 Issue。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
<source>Restore Default</source>
<translation>還原預設值</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="359"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
<source>Clear</source>
<translation>清除</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="387"/>
<source>Conflicting Button Sequence</source>
<translation>按鍵衝突</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="381"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="388"/>
<source>The default button sequence is already assigned to: %1</source>
<translation>預設的按鍵序列已分配給: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="395"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="402"/>
<source>The default key sequence is already assigned to: %1</source>
<translation>預設金鑰已指定給:%1</translation>
</message>
@@ -3372,67 +3362,72 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>显示“文件类型”列</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="110"/>
+ <source>Show Play Time Column</source>
+ <translation>显示“游玩时间”列</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
<source>Game Icon Size:</source>
<translation>遊戲圖示大小:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="133"/>
<source>Folder Icon Size:</source>
<translation>資料夾圖示大小:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="147"/>
<source>Row 1 Text:</source>
<translation>第一行顯示文字:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="161"/>
<source>Row 2 Text:</source>
<translation>第二行顯示文字:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="178"/>
<source>Screenshots</source>
<translation>螢幕截圖</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="179"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="186"/>
<source>Ask Where To Save Screenshots (Windows Only)</source>
<translation>詢問儲存螢幕截圖的位置(僅限 Windows)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="195"/>
<source>Screenshots Path: </source>
<translation>螢幕截圖位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="198"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="205"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="221"/>
<source>TextLabel</source>
<translation>文本标签</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="240"/>
<source>Resolution:</source>
<translation>解析度:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="146"/>
<source>Select Screenshots Path...</source>
<translation>選擇儲存螢幕截圖位置...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="288"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="293"/>
<source>&lt;System&gt;</source>
<translation>&lt;System&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="393"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="398"/>
<source>Auto (%1 x %2, %3 x %4)</source>
<comment>Screenshot width value</comment>
<translation>自动 (%1 x %2, %3 x %4)</translation>
@@ -3750,819 +3745,823 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="205"/>
+ <location filename="../../src/yuzu/main.cpp" line="211"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>我們&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;蒐集匿名的資料&lt;/a&gt;以幫助改善 yuzu。&lt;br/&gt;&lt;br/&gt;您願意和我們分享您的使用資料嗎?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="208"/>
+ <location filename="../../src/yuzu/main.cpp" line="214"/>
<source>Telemetry</source>
<translation>遙測</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="441"/>
+ <location filename="../../src/yuzu/main.cpp" line="449"/>
<source>Broken Vulkan Installation Detected</source>
<translation>检测到 Vulkan 的安装已损坏</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="442"/>
+ <location filename="../../src/yuzu/main.cpp" line="450"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Vulkan 初始化失败。&lt;br&gt;&lt;br&gt;点击&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;这里&lt;/a&gt;获取此问题的相关信息。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="467"/>
+ <location filename="../../src/yuzu/main.cpp" line="475"/>
<source>Running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>游戏正在运行</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="848"/>
+ <location filename="../../src/yuzu/main.cpp" line="856"/>
<source>Loading Web Applet...</source>
<translation>載入 Web Applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="898"/>
- <location filename="../../src/yuzu/main.cpp" line="901"/>
+ <location filename="../../src/yuzu/main.cpp" line="906"/>
+ <location filename="../../src/yuzu/main.cpp" line="909"/>
<source>Disable Web Applet</source>
<translation>停用 Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="902"/>
+ <location filename="../../src/yuzu/main.cpp" line="910"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>禁用 Web 应用程序可能会导致未知的行为,且只能在《超级马里奥 3D 全明星》中使用。您确定要禁用 Web 应用程序吗?
(您可以在调试选项中重新启用它。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1018"/>
+ <location filename="../../src/yuzu/main.cpp" line="1026"/>
<source>The amount of shaders currently being built</source>
<translation>目前正在建構的著色器數量</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1020"/>
+ <location filename="../../src/yuzu/main.cpp" line="1028"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>目前選擇的解析度縮放比例。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1023"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>目前的模擬速度。高於或低於 100% 表示比實際 Switch 執行速度更快或更慢。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1026"/>
+ <location filename="../../src/yuzu/main.cpp" line="1034"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>遊戲即時 FPS。會因遊戲和場景的不同而改變。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1030"/>
+ <location filename="../../src/yuzu/main.cpp" line="1038"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>在不考慮幀數限制和垂直同步的情況下模擬一個 Switch 畫格的實際時間,若要全速模擬,此數值不得超過 16.67 毫秒。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Unmute</source>
<translation>取消靜音</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1085"/>
+ <location filename="../../src/yuzu/main.cpp" line="1093"/>
<source>Mute</source>
<translation>靜音</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1090"/>
+ <location filename="../../src/yuzu/main.cpp" line="1098"/>
<source>Reset Volume</source>
<translation>重設音量</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1274"/>
+ <location filename="../../src/yuzu/main.cpp" line="1284"/>
<source>&amp;Clear Recent Files</source>
<translation>清除最近的檔案(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1361"/>
+ <location filename="../../src/yuzu/main.cpp" line="1371"/>
<source>Emulated mouse is enabled</source>
<translation>模擬滑鼠已啟用</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1362"/>
+ <location filename="../../src/yuzu/main.cpp" line="1372"/>
<source>Real mouse input and mouse panning are incompatible. Please disable the emulated mouse in input advanced settings to allow mouse panning.</source>
<translation>实体鼠标输入与鼠标平移不兼容。请在高级输入设置中禁用模拟鼠标以使用鼠标平移。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1588"/>
+ <location filename="../../src/yuzu/main.cpp" line="1624"/>
<source>&amp;Continue</source>
<translation>繼續(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1590"/>
+ <location filename="../../src/yuzu/main.cpp" line="1626"/>
<source>&amp;Pause</source>
<translation>&amp;暫停</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1762"/>
+ <location filename="../../src/yuzu/main.cpp" line="1796"/>
<source>Warning Outdated Game Format</source>
<translation>過時遊戲格式警告</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1763"/>
+ <location filename="../../src/yuzu/main.cpp" line="1797"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>此遊戲為解構的 ROM 資料夾格式,這是一種過時的格式,已被其他格式取代,如 NCA、NAX、XCI、NSP。解構的 ROM 目錄缺少圖示、中繼資料和更新支援。&lt;br&gt;&lt;br&gt;有關 yuzu 支援的各種 Switch 格式說明,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;請參閱我們的 wiki &lt;/a&gt;。此訊息將不再顯示。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1775"/>
<location filename="../../src/yuzu/main.cpp" line="1809"/>
+ <location filename="../../src/yuzu/main.cpp" line="1843"/>
<source>Error while loading ROM!</source>
<translation>載入 ROM 時發生錯誤!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1776"/>
+ <location filename="../../src/yuzu/main.cpp" line="1810"/>
<source>The ROM format is not supported.</source>
<translation>此 ROM 格式不支援</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1780"/>
+ <location filename="../../src/yuzu/main.cpp" line="1814"/>
<source>An error occurred initializing the video core.</source>
<translation>初始化視訊核心時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1781"/>
+ <location filename="../../src/yuzu/main.cpp" line="1815"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu 在執行視訊核心時發生錯誤。 這可能是 GPU 驅動程序過舊造成的。 詳細資訊請查閱日誌檔案。 關於日誌檔案的更多資訊,請參考以下頁面:&lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;如何上傳日誌檔案&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1796"/>
+ <location filename="../../src/yuzu/main.cpp" line="1830"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>載入 ROM 時發生錯誤!%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1799"/>
+ <location filename="../../src/yuzu/main.cpp" line="1833"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;請參閱 &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速指引&lt;/a&gt;以重新傾印檔案。&lt;br&gt;您可以前往 yuzu 的 wiki&lt;/a&gt; 或 Discord 社群&lt;/a&gt;以獲得幫助。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1810"/>
+ <location filename="../../src/yuzu/main.cpp" line="1844"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>發生未知錯誤,請檢視紀錄了解細節。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1991"/>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1992"/>
+ <location filename="../../src/yuzu/main.cpp" line="2026"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2058"/>
+ <location filename="../../src/yuzu/main.cpp" line="2092"/>
<source>Closing software...</source>
<translation>正在關閉軟體…</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <location filename="../../src/yuzu/main.cpp" line="2246"/>
<source>Save Data</source>
<translation>儲存資料</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2266"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>Mod Data</source>
<translation>模組資料</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2279"/>
+ <location filename="../../src/yuzu/main.cpp" line="2315"/>
<source>Error Opening %1 Folder</source>
<translation>開啟資料夾 %1 時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2280"/>
- <location filename="../../src/yuzu/main.cpp" line="2964"/>
+ <location filename="../../src/yuzu/main.cpp" line="2316"/>
+ <location filename="../../src/yuzu/main.cpp" line="3030"/>
<source>Folder does not exist!</source>
<translation>資料夾不存在</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2292"/>
+ <location filename="../../src/yuzu/main.cpp" line="2328"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>開啟通用著色器快取位置時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2293"/>
+ <location filename="../../src/yuzu/main.cpp" line="2329"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>無法新增此遊戲的著色器快取資料夾。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
<source>Error Removing Contents</source>
<translation>移除內容時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2368"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Error Removing Update</source>
<translation>移除更新時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2370"/>
+ <location filename="../../src/yuzu/main.cpp" line="2406"/>
<source>Error Removing DLC</source>
<translation>移除 DLC 時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2415"/>
<source>Remove Installed Game Contents?</source>
<translation>移除已安裝的遊戲內容?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2381"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Remove Installed Game Update?</source>
<translation>移除已安裝的遊戲更新?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2383"/>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
<source>Remove Installed Game DLC?</source>
<translation>移除已安裝的遊戲 DLC?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2389"/>
+ <location filename="../../src/yuzu/main.cpp" line="2425"/>
<source>Remove Entry</source>
<translation>移除項目</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2420"/>
- <location filename="../../src/yuzu/main.cpp" line="2436"/>
- <location filename="../../src/yuzu/main.cpp" line="2467"/>
- <location filename="../../src/yuzu/main.cpp" line="2535"/>
- <location filename="../../src/yuzu/main.cpp" line="2569"/>
- <location filename="../../src/yuzu/main.cpp" line="2592"/>
+ <location filename="../../src/yuzu/main.cpp" line="2455"/>
+ <location filename="../../src/yuzu/main.cpp" line="2471"/>
+ <location filename="../../src/yuzu/main.cpp" line="2502"/>
+ <location filename="../../src/yuzu/main.cpp" line="2581"/>
+ <location filename="../../src/yuzu/main.cpp" line="2615"/>
+ <location filename="../../src/yuzu/main.cpp" line="2638"/>
<source>Successfully Removed</source>
<translation>移除成功</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2421"/>
+ <location filename="../../src/yuzu/main.cpp" line="2456"/>
<source>Successfully removed the installed base game.</source>
<translation>成功移除已安裝的遊戲。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2460"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>此遊戲並非安裝在內部儲存空間,因此無法移除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2437"/>
+ <location filename="../../src/yuzu/main.cpp" line="2472"/>
<source>Successfully removed the installed update.</source>
<translation>成功移除已安裝的遊戲更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2475"/>
<source>There is no update installed for this title.</source>
<translation>此遊戲沒有已安裝的更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <location filename="../../src/yuzu/main.cpp" line="2498"/>
<source>There are no DLC installed for this title.</source>
<translation>此遊戲沒有已安裝的 DLC。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2468"/>
+ <location filename="../../src/yuzu/main.cpp" line="2503"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>成功移除遊戲 %1 已安裝的 DLC。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2511"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>刪除 OpenGL 模式的著色器快取?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2478"/>
+ <location filename="../../src/yuzu/main.cpp" line="2513"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>刪除 Vulkan 模式的著色器快取?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2480"/>
+ <location filename="../../src/yuzu/main.cpp" line="2515"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>刪除所有的著色器快取?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2482"/>
+ <location filename="../../src/yuzu/main.cpp" line="2517"/>
<source>Remove Custom Game Configuration?</source>
<translation>移除額外遊戲設定?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2519"/>
<source>Remove Cache Storage?</source>
<translation>移除快取儲存空間?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2490"/>
+ <location filename="../../src/yuzu/main.cpp" line="2525"/>
<source>Remove File</source>
<translation>刪除檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2530"/>
- <location filename="../../src/yuzu/main.cpp" line="2538"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Remove Play Time Data</source>
+ <translation>清除游玩时间</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
+ <source>Reset play time?</source>
+ <translation>重置游玩时间?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2576"/>
+ <location filename="../../src/yuzu/main.cpp" line="2584"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>刪除通用著色器快取時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2531"/>
- <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <location filename="../../src/yuzu/main.cpp" line="2577"/>
+ <location filename="../../src/yuzu/main.cpp" line="2611"/>
<source>A shader cache for this title does not exist.</source>
<translation>此遊戲沒有著色器快取</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2582"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>成功刪除著色器快取。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2585"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>刪除通用著色器快取失敗。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2554"/>
+ <location filename="../../src/yuzu/main.cpp" line="2600"/>
<source>Error Removing Vulkan Driver Pipeline Cache</source>
<translation>移除 Vulkan 驅動程式管線快取時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2601"/>
<source>Failed to remove the driver pipeline cache.</source>
<translation>無法移除驅動程式管線快取。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2564"/>
- <location filename="../../src/yuzu/main.cpp" line="2572"/>
+ <location filename="../../src/yuzu/main.cpp" line="2610"/>
+ <location filename="../../src/yuzu/main.cpp" line="2618"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>刪除通用著色器快取時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2570"/>
+ <location filename="../../src/yuzu/main.cpp" line="2616"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>成功刪除通用著色器快取。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2573"/>
+ <location filename="../../src/yuzu/main.cpp" line="2619"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>無法刪除著色器快取資料夾。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2586"/>
- <location filename="../../src/yuzu/main.cpp" line="2595"/>
+ <location filename="../../src/yuzu/main.cpp" line="2632"/>
+ <location filename="../../src/yuzu/main.cpp" line="2641"/>
<source>Error Removing Custom Configuration</source>
<translation>移除額外遊戲設定時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2587"/>
+ <location filename="../../src/yuzu/main.cpp" line="2633"/>
<source>A custom configuration for this title does not exist.</source>
<translation>此遊戲沒有額外設定。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2593"/>
+ <location filename="../../src/yuzu/main.cpp" line="2639"/>
<source>Successfully removed the custom game configuration.</source>
<translation>成功移除額外遊戲設定。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2596"/>
+ <location filename="../../src/yuzu/main.cpp" line="2642"/>
<source>Failed to remove the custom game configuration.</source>
<translation>移除額外遊戲設定失敗。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2618"/>
- <location filename="../../src/yuzu/main.cpp" line="2706"/>
+ <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2752"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS 抽取失敗!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2619"/>
+ <location filename="../../src/yuzu/main.cpp" line="2665"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>複製 RomFS 檔案時發生錯誤或使用者取消動作。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Full</source>
<translation>全部</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2681"/>
+ <location filename="../../src/yuzu/main.cpp" line="2727"/>
<source>Skeleton</source>
<translation>部分</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2683"/>
+ <location filename="../../src/yuzu/main.cpp" line="2729"/>
<source>Select RomFS Dump Mode</source>
<translation>選擇RomFS傾印模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2684"/>
+ <location filename="../../src/yuzu/main.cpp" line="2730"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>請選擇如何傾印 RomFS。&lt;br&gt;「全部」會複製所有檔案到新資料夾中,而&lt;br&gt;「部分」只會建立資料夾結構。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2707"/>
+ <location filename="../../src/yuzu/main.cpp" line="2753"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 沒有足夠的空間用於抽取 RomFS。請確保有足夠的空間或於模擬 &gt; 設定 &gt;系統 &gt;檔案系統 &gt; 傾印根目錄中選擇其他資料夾。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
<source>Extracting RomFS...</source>
<translation>抽取 RomFS 中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2714"/>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="3102"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2760"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Cancel</source>
<translation>取消</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2724"/>
+ <location filename="../../src/yuzu/main.cpp" line="2770"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS 抽取完成!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2725"/>
- <location filename="../../src/yuzu/main.cpp" line="2779"/>
- <location filename="../../src/yuzu/main.cpp" line="4115"/>
+ <location filename="../../src/yuzu/main.cpp" line="2771"/>
+ <location filename="../../src/yuzu/main.cpp" line="2825"/>
+ <location filename="../../src/yuzu/main.cpp" line="4252"/>
<source>The operation completed successfully.</source>
<translation>動作已成功完成</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2736"/>
+ <location filename="../../src/yuzu/main.cpp" line="2782"/>
<source>Integrity verification couldn&apos;t be performed!</source>
<translation>无法执行完整性验证!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2737"/>
+ <location filename="../../src/yuzu/main.cpp" line="2783"/>
<source>File contents were not checked for validity.</source>
<translation>未检查文件的完整性。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2740"/>
- <location filename="../../src/yuzu/main.cpp" line="4111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2786"/>
+ <location filename="../../src/yuzu/main.cpp" line="4248"/>
<source>Integrity verification failed!</source>
<translation>完整性验证失败!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2741"/>
+ <location filename="../../src/yuzu/main.cpp" line="2787"/>
<source>File contents may be corrupt.</source>
<translation>文件可能已经损坏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2750"/>
- <location filename="../../src/yuzu/main.cpp" line="4023"/>
+ <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="4160"/>
<source>Verifying integrity...</source>
<translation>正在验证完整性...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2778"/>
- <location filename="../../src/yuzu/main.cpp" line="4114"/>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <location filename="../../src/yuzu/main.cpp" line="4251"/>
<source>Integrity verification succeeded!</source>
<translation>完整性验证成功!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2817"/>
- <location filename="../../src/yuzu/main.cpp" line="2841"/>
- <location filename="../../src/yuzu/main.cpp" line="2851"/>
- <location filename="../../src/yuzu/main.cpp" line="2933"/>
- <location filename="../../src/yuzu/main.cpp" line="2941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2862"/>
+ <location filename="../../src/yuzu/main.cpp" line="2902"/>
+ <location filename="../../src/yuzu/main.cpp" line="2999"/>
+ <location filename="../../src/yuzu/main.cpp" line="3007"/>
<source>Create Shortcut</source>
<translation>建立捷徑</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2818"/>
+ <location filename="../../src/yuzu/main.cpp" line="2863"/>
<source>This will create a shortcut to the current AppImage. This may not work well if you update. Continue?</source>
<translation>這將會為目前的應用程式映像建立捷徑,可能在其更新後無法運作,仍要繼續嗎?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2842"/>
- <source>Cannot create shortcut on desktop. Path &quot;%1&quot; does not exist.</source>
- <translation>無法在桌面上建立捷徑,路徑「%1」不存在。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="2852"/>
- <source>Cannot create shortcut in applications menu. Path &quot;%1&quot; does not exist and cannot be created.</source>
- <translation>無法在應用程式選單中建立捷徑,路徑「%1」不存在且無法建立。</translation>
+ <location filename="../../src/yuzu/main.cpp" line="2903"/>
+ <source>Cannot create shortcut. Path &quot;%1&quot; does not exist.</source>
+ <translation>无法创建快捷方式。路径“ %1 ”不存在。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2869"/>
+ <location filename="../../src/yuzu/main.cpp" line="2922"/>
<source>Create Icon</source>
<translation>建立圖示</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2870"/>
+ <location filename="../../src/yuzu/main.cpp" line="2923"/>
<source>Cannot create icon file. Path &quot;%1&quot; does not exist and cannot be created.</source>
<translation>無法建立圖示檔案,路徑「%1」不存在且無法建立。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2921"/>
+ <location filename="../../src/yuzu/main.cpp" line="2992"/>
<source>Start %1 with the yuzu Emulator</source>
<translation>使用 yuzu 模擬器啟動 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2934"/>
+ <location filename="../../src/yuzu/main.cpp" line="3000"/>
<source>Failed to create a shortcut at %1</source>
<translation>無法在 %1 建立捷徑</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2942"/>
+ <location filename="../../src/yuzu/main.cpp" line="3008"/>
<source>Successfully created a shortcut to %1</source>
<translation>已成功在 %1 建立捷徑</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2963"/>
+ <location filename="../../src/yuzu/main.cpp" line="3029"/>
<source>Error Opening %1</source>
<translation>開啟 %1 時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2972"/>
+ <location filename="../../src/yuzu/main.cpp" line="3038"/>
<source>Select Directory</source>
<translation>選擇資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3001"/>
+ <location filename="../../src/yuzu/main.cpp" line="3067"/>
<source>Properties</source>
<translation>屬性</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3002"/>
+ <location filename="../../src/yuzu/main.cpp" line="3068"/>
<source>The game properties could not be loaded.</source>
<translation>無法載入遊戲屬性</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3019"/>
+ <location filename="../../src/yuzu/main.cpp" line="3085"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch 執行檔 (%1);;所有檔案 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3023"/>
+ <location filename="../../src/yuzu/main.cpp" line="3089"/>
<source>Load File</source>
<translation>開啟檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3036"/>
+ <location filename="../../src/yuzu/main.cpp" line="3102"/>
<source>Open Extracted ROM Directory</source>
<translation>開啟已抽取的 ROM 資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3047"/>
+ <location filename="../../src/yuzu/main.cpp" line="3113"/>
<source>Invalid Directory Selected</source>
<translation>選擇的資料夾無效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3048"/>
+ <location filename="../../src/yuzu/main.cpp" line="3114"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>選擇的資料夾未包含「main」檔案。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3058"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>可安装的 Switch 檔案 (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX 卡帶映像 (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3063"/>
+ <location filename="../../src/yuzu/main.cpp" line="3129"/>
<source>Install Files</source>
<translation>安裝檔案</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3109"/>
+ <location filename="../../src/yuzu/main.cpp" line="3175"/>
<source>%n file(s) remaining</source>
<translation><numerusform>剩餘 %n 個檔案</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3111"/>
+ <location filename="../../src/yuzu/main.cpp" line="3177"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>正在安裝檔案「%1」...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3156"/>
- <location filename="../../src/yuzu/main.cpp" line="3170"/>
+ <location filename="../../src/yuzu/main.cpp" line="3222"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Install Results</source>
<translation>安裝結果</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3157"/>
+ <location filename="../../src/yuzu/main.cpp" line="3223"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>為了避免潛在的衝突,不建議將遊戲本體安裝至內部儲存空間。
此功能僅用於安裝遊戲更新和 DLC。</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3163"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>最近安裝了 %n 個檔案
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3166"/>
+ <location filename="../../src/yuzu/main.cpp" line="3232"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n 個檔案被取代
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3168"/>
+ <location filename="../../src/yuzu/main.cpp" line="3234"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n 個檔案安裝失敗</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <location filename="../../src/yuzu/main.cpp" line="3333"/>
<source>System Application</source>
<translation>系統應用程式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
+ <location filename="../../src/yuzu/main.cpp" line="3334"/>
<source>System Archive</source>
<translation>系統檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
+ <location filename="../../src/yuzu/main.cpp" line="3335"/>
<source>System Application Update</source>
<translation>系統應用程式更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3270"/>
+ <location filename="../../src/yuzu/main.cpp" line="3336"/>
<source>Firmware Package (Type A)</source>
<translation>韌體包(A型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <location filename="../../src/yuzu/main.cpp" line="3337"/>
<source>Firmware Package (Type B)</source>
<translation>韌體包(B型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3272"/>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
<source>Game</source>
<translation>遊戲</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3273"/>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
<source>Game Update</source>
<translation>遊戲更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3274"/>
+ <location filename="../../src/yuzu/main.cpp" line="3340"/>
<source>Game DLC</source>
<translation>遊戲 DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3275"/>
+ <location filename="../../src/yuzu/main.cpp" line="3341"/>
<source>Delta Title</source>
<translation>Delta Title</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3344"/>
<source>Select NCA Install Type...</source>
<translation>選擇 NCA 安裝類型...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3279"/>
+ <location filename="../../src/yuzu/main.cpp" line="3345"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>請選擇此 NCA 的安裝類型:
(在多數情況下,選擇預設的「遊戲」即可。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3285"/>
+ <location filename="../../src/yuzu/main.cpp" line="3351"/>
<source>Failed to Install</source>
<translation>安裝失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <location filename="../../src/yuzu/main.cpp" line="3352"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>選擇的 NCA 安裝類型無效。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3321"/>
+ <location filename="../../src/yuzu/main.cpp" line="3387"/>
<source>File not found</source>
<translation>找不到檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3322"/>
+ <location filename="../../src/yuzu/main.cpp" line="3388"/>
<source>File &quot;%1&quot; not found</source>
<translation>找不到「%1」檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>OK</source>
<translation>確定</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3426"/>
- <location filename="../../src/yuzu/main.cpp" line="3445"/>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3542"/>
<source>Hardware requirements not met</source>
<translation>硬體不符合需求</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3427"/>
- <location filename="../../src/yuzu/main.cpp" line="3446"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
+ <location filename="../../src/yuzu/main.cpp" line="3543"/>
<source>Your system does not meet the recommended hardware requirements. Compatibility reporting has been disabled.</source>
<translation>您的系統不符合建議的硬體需求,相容性回報已停用。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3438"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
<source>Missing yuzu Account</source>
<translation>未設定 yuzu 帳號</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3536"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>為了上傳相容性測試結果,您必須登入 yuzu 帳號。&lt;br&gt;&lt;br/&gt;欲登入 yuzu 帳號請至模擬 &amp;gt; 設定 &amp;gt; 網路。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3454"/>
+ <location filename="../../src/yuzu/main.cpp" line="3551"/>
<source>Error opening URL</source>
<translation>開啟 URL 時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3552"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>無法開啟 URL:「%1」。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3760"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>TAS Recording</source>
<translation>TAS 錄製</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3761"/>
+ <location filename="../../src/yuzu/main.cpp" line="3854"/>
<source>Overwrite file of player 1?</source>
<translation>覆寫玩家 1 的檔案?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3873"/>
<source>Invalid config detected</source>
<translation>偵測到無效設定</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3788"/>
+ <location filename="../../src/yuzu/main.cpp" line="3874"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>掌機手把無法在主機模式中使用。將會選擇 Pro 手把。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3962"/>
- <location filename="../../src/yuzu/main.cpp" line="3990"/>
+ <location filename="../../src/yuzu/main.cpp" line="4076"/>
+ <location filename="../../src/yuzu/main.cpp" line="4127"/>
<source>The current amiibo has been removed</source>
<translation>目前 Amiibo 已被移除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
<source>Error</source>
<translation>錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3967"/>
- <location filename="../../src/yuzu/main.cpp" line="4002"/>
+ <location filename="../../src/yuzu/main.cpp" line="4081"/>
+ <location filename="../../src/yuzu/main.cpp" line="4139"/>
<source>The current game is not looking for amiibos</source>
<translation>目前遊戲並未在尋找 Amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3973"/>
+ <location filename="../../src/yuzu/main.cpp" line="4087"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo 檔案 (%1);; 所有檔案 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3974"/>
+ <location filename="../../src/yuzu/main.cpp" line="4088"/>
<source>Load Amiibo</source>
<translation>開啟 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3986"/>
+ <location filename="../../src/yuzu/main.cpp" line="4123"/>
<source>Error loading Amiibo data</source>
<translation>載入 Amiibo 資料時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3996"/>
+ <location filename="../../src/yuzu/main.cpp" line="4133"/>
<source>The selected file is not a valid amiibo</source>
<translation>選取的檔案不是有效的 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3999"/>
+ <location filename="../../src/yuzu/main.cpp" line="4136"/>
<source>The selected file is already on use</source>
<translation>選取的檔案已在使用中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4005"/>
+ <location filename="../../src/yuzu/main.cpp" line="4142"/>
<source>An unknown error occurred</source>
<translation>發生了未知錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4112"/>
+ <location filename="../../src/yuzu/main.cpp" line="4249"/>
<source>Verification failed for the following files:
%1</source>
@@ -4571,145 +4570,177 @@ Please, only use this feature to install updates and DLC.</source>
%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4141"/>
+ <location filename="../../src/yuzu/main.cpp" line="4278"/>
+ <location filename="../../src/yuzu/main.cpp" line="4301"/>
+ <location filename="../../src/yuzu/main.cpp" line="4325"/>
<source>No firmware available</source>
<translation>无可用固件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4142"/>
+ <location filename="../../src/yuzu/main.cpp" line="4279"/>
+ <source>Please install the firmware to use the Album applet.</source>
+ <translation>请安装固件以使用相册小程序。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4285"/>
+ <source>Album Applet</source>
+ <translation>相册小程序</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4286"/>
+ <source>Album applet is not available. Please reinstall firmware.</source>
+ <translation>相册小程序不可用。请安装固件。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4302"/>
+ <source>Please install the firmware to use the Cabinet applet.</source>
+ <translation>请安装固件以使用 Cabinet 小程序。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4308"/>
+ <source>Cabinet Applet</source>
+ <translation>Cabinet 小程序</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4309"/>
+ <source>Cabinet applet is not available. Please reinstall firmware.</source>
+ <translation>Cabinet 小程序不可用。请安装固件。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="4326"/>
<source>Please install the firmware to use the Mii editor.</source>
<translation>请安装固件以使用 Mii editor。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4148"/>
+ <location filename="../../src/yuzu/main.cpp" line="4332"/>
<source>Mii Edit Applet</source>
<translation>MiiEdit 小程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4149"/>
+ <location filename="../../src/yuzu/main.cpp" line="4333"/>
<source>Mii editor is not available. Please reinstall firmware.</source>
<translation>Mii editor 不可用。请安装固件。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4180"/>
+ <location filename="../../src/yuzu/main.cpp" line="4366"/>
<source>Capture Screenshot</source>
<translation>截圖</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4181"/>
+ <location filename="../../src/yuzu/main.cpp" line="4367"/>
<source>PNG Image (*.png)</source>
<translation>PNG 圖片 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4264"/>
+ <location filename="../../src/yuzu/main.cpp" line="4450"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 狀態:正在執行 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4268"/>
+ <location filename="../../src/yuzu/main.cpp" line="4454"/>
<source>TAS state: Recording %1</source>
<translation>TAS 狀態:正在錄製 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4270"/>
+ <location filename="../../src/yuzu/main.cpp" line="4456"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 狀態:閒置 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4274"/>
+ <location filename="../../src/yuzu/main.cpp" line="4460"/>
<source>TAS State: Invalid</source>
<translation>TAS 狀態:無效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Stop Running</source>
<translation>&amp;停止執行</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4288"/>
+ <location filename="../../src/yuzu/main.cpp" line="4474"/>
<source>&amp;Start</source>
<translation>開始(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>Stop R&amp;ecording</source>
<translation>停止錄製</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4289"/>
+ <location filename="../../src/yuzu/main.cpp" line="4475"/>
<source>R&amp;ecord</source>
<translation>錄製 (&amp;E)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="4313"/>
+ <location filename="../../src/yuzu/main.cpp" line="4499"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>正在編譯 %n 個著色器檔案</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4322"/>
+ <location filename="../../src/yuzu/main.cpp" line="4508"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>縮放比例:%1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4325"/>
+ <location filename="../../src/yuzu/main.cpp" line="4511"/>
<source>Speed: %1% / %2%</source>
<translation>速度:%1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4329"/>
+ <location filename="../../src/yuzu/main.cpp" line="4515"/>
<source>Speed: %1%</source>
<translation>速度:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4333"/>
+ <location filename="../../src/yuzu/main.cpp" line="4519"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>遊戲: %1 FPS(未限制)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4336"/>
+ <location filename="../../src/yuzu/main.cpp" line="4522"/>
<source>Game: %1 FPS</source>
<translation>遊戲:%1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4338"/>
+ <location filename="../../src/yuzu/main.cpp" line="4524"/>
<source>Frame: %1 ms</source>
<translation>畫格延遲:%1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4365"/>
+ <location filename="../../src/yuzu/main.cpp" line="4551"/>
<source>%1 %2</source>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4375"/>
+ <location filename="../../src/yuzu/main.cpp" line="4561"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4383"/>
+ <location filename="../../src/yuzu/main.cpp" line="4569"/>
<source>NO AA</source>
<translation>抗鋸齒關</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4392"/>
+ <location filename="../../src/yuzu/main.cpp" line="4578"/>
<source>VOLUME: MUTE</source>
<translation>音量: 靜音</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4395"/>
+ <location filename="../../src/yuzu/main.cpp" line="4581"/>
<source>VOLUME: %1%</source>
<comment>Volume percentage (e.g. 50%)</comment>
<translation>音量: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4476"/>
+ <location filename="../../src/yuzu/main.cpp" line="4662"/>
<source>Confirm Key Rederivation</source>
<translation>確認重新產生金鑰</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4477"/>
+ <location filename="../../src/yuzu/main.cpp" line="4663"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -4725,37 +4756,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
這將刪除您自動產生的金鑰檔案並重新執行產生金鑰模組。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4511"/>
+ <location filename="../../src/yuzu/main.cpp" line="4697"/>
<source>Missing fuses</source>
<translation>遺失項目</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4514"/>
+ <location filename="../../src/yuzu/main.cpp" line="4700"/>
<source> - Missing BOOT0</source>
<translation>- 遺失 BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4517"/>
+ <location filename="../../src/yuzu/main.cpp" line="4703"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - 遺失 BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4520"/>
+ <location filename="../../src/yuzu/main.cpp" line="4706"/>
<source> - Missing PRODINFO</source>
<translation>- 遺失 PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4525"/>
+ <location filename="../../src/yuzu/main.cpp" line="4711"/>
<source>Derivation Components Missing</source>
<translation>遺失產生元件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4526"/>
+ <location filename="../../src/yuzu/main.cpp" line="4712"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>缺少加密金鑰。 &lt;br&gt;請按照&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;《Yuzu快速入門指南》來取得所有金鑰、韌體、遊戲&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4535"/>
+ <location filename="../../src/yuzu/main.cpp" line="4721"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -4764,49 +4795,49 @@ on your system&apos;s performance.</source>
您的系統效能。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4537"/>
+ <location filename="../../src/yuzu/main.cpp" line="4723"/>
<source>Deriving Keys</source>
<translation>產生金鑰</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4554"/>
+ <location filename="../../src/yuzu/main.cpp" line="4740"/>
<source>System Archive Decryption Failed</source>
<translation>系統封存解密失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4555"/>
+ <location filename="../../src/yuzu/main.cpp" line="4741"/>
<source>Encryption keys failed to decrypt firmware. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.</source>
<translation>加密金鑰無法解密韌體。&lt;br&gt;請依循&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速開始指南&lt;/a&gt;以取得您的金鑰、韌體和遊戲。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4642"/>
+ <location filename="../../src/yuzu/main.cpp" line="4834"/>
<source>Select RomFS Dump Target</source>
<translation>選擇 RomFS 傾印目標</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4643"/>
+ <location filename="../../src/yuzu/main.cpp" line="4835"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>請選擇希望傾印的 RomFS。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4661"/>
+ <location filename="../../src/yuzu/main.cpp" line="4853"/>
<source>Are you sure you want to close yuzu?</source>
<translation>您確定要關閉 yuzu 嗎?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4662"/>
- <location filename="../../src/yuzu/main.cpp" line="4757"/>
- <location filename="../../src/yuzu/main.cpp" line="4770"/>
+ <location filename="../../src/yuzu/main.cpp" line="4854"/>
+ <location filename="../../src/yuzu/main.cpp" line="4949"/>
+ <location filename="../../src/yuzu/main.cpp" line="4961"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4758"/>
+ <location filename="../../src/yuzu/main.cpp" line="4950"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>您確定要停止模擬嗎?未儲存的進度將會遺失。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="4767"/>
+ <location filename="../../src/yuzu/main.cpp" line="4958"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -4958,241 +4989,251 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameList</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="542"/>
<source>Favorite</source>
<translation>我的最愛</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
<source>Start Game</source>
<translation>開始遊戲</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="540"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
<source>Start Game without Custom Configuration</source>
<translation>開始遊戲(不使用額外設定)</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="542"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
<source>Open Save Data Location</source>
<translation>開啟存檔位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="549"/>
<source>Open Mod Data Location</source>
<translation>開啟模組位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
<source>Open Transferable Pipeline Cache</source>
<translation>開啟通用著色器管線快取位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Remove</source>
<translation>移除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
<source>Remove Installed Update</source>
<translation>移除已安裝的遊戲更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="549"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
<source>Remove All Installed DLC</source>
<translation>移除所有安裝的遊戲更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
<source>Remove Custom Configuration</source>
<translation>移除額外設定</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="557"/>
+ <source>Remove Play Time Data</source>
+ <translation>清除游玩时间</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
<source>Remove Cache Storage</source>
<translation>移除快取儲存空間</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="559"/>
<source>Remove OpenGL Pipeline Cache</source>
<translation>刪除 OpenGL 著色器管線快取</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="560"/>
<source>Remove Vulkan Pipeline Cache</source>
<translation>刪除 Vulkan 著色器管線快取</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="562"/>
<source>Remove All Pipeline Caches</source>
<translation>刪除所有著色器管線快取</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="563"/>
<source>Remove All Installed Contents</source>
<translation>移除所有安裝項目</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="557"/>
- <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="565"/>
<source>Dump RomFS</source>
<translation>傾印 RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="559"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="566"/>
<source>Dump RomFS to SDMC</source>
<translation>傾印 RomFS 到 SDMC</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="560"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="567"/>
<source>Verify Integrity</source>
<translation>完整性验证</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="561"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="568"/>
<source>Copy Title ID to Clipboard</source>
<translation>複製遊戲 ID 到剪貼簿</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="562"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="569"/>
<source>Navigate to GameDB entry</source>
<translation>檢視遊戲相容性報告</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="564"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="570"/>
<source>Create Shortcut</source>
<translation>建立捷徑</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="565"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="571"/>
<source>Add to Desktop</source>
<translation>新增至桌面</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="567"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="574"/>
<source>Add to Applications Menu</source>
<translation>新增至應用程式選單</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="570"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="577"/>
<source>Properties</source>
<translation>屬性</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="657"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="666"/>
<source>Scan Subfolders</source>
<translation>包含子資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="658"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="667"/>
<source>Remove Game Directory</source>
<translation>移除遊戲資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="677"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="686"/>
<source>▲ Move Up</source>
<translation>▲ 向上移動</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="678"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="687"/>
<source>▼ Move Down</source>
<translation>▼ 向下移動</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="679"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="688"/>
<source>Open Directory Location</source>
<translation>開啟資料夾位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="724"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="733"/>
<source>Clear</source>
<translation>清除</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="788"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="797"/>
<source>Name</source>
<translation>名稱</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="789"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="798"/>
<source>Compatibility</source>
<translation>相容性</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="790"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="799"/>
<source>Add-ons</source>
<translation>延伸模組</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="791"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="800"/>
<source>File type</source>
<translation>檔案格式</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="792"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="801"/>
<source>Size</source>
<translation>大小</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="802"/>
+ <source>Play time</source>
+ <translation>游玩时间</translation>
+ </message>
</context>
<context>
<name>GameListItemCompat</name>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Ingame</source>
<translation>遊戲內</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
<source>Game starts, but crashes or major glitches prevent it from being completed.</source>
<translation>遊戲可以執行,但可能會出現當機或故障導致遊戲無法正常運作。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Perfect</source>
<translation>完美</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game can be played without issues.</source>
<translation>遊戲可以毫無問題的遊玩。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Playable</source>
<translation>可遊玩</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game functions with minor graphical or audio glitches and is playable from start to finish.</source>
<translation>遊戲自始至終可以正常遊玩,但可能會有一些輕微的圖形或音訊故障。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Intro/Menu</source>
<translation>開始畫面/選單</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="156"/>
<source>Game loads, but is unable to progress past the Start Screen.</source>
<translation>遊戲可以載入,但無法通過開始畫面。</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>Won&apos;t Boot</source>
<translation>無法啟動</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="156"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="157"/>
<source>The game crashes when attempting to startup.</source>
<translation>啟動遊戲時異常關閉</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>Not Tested</source>
<translation>未測試</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="157"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="158"/>
<source>The game has not yet been tested.</source>
<translation>此遊戲尚未經過測試</translation>
</message>
@@ -5200,7 +5241,7 @@ Would you like to bypass this and exit anyway?</source>
<context>
<name>GameListPlaceholder</name>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="965"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="970"/>
<source>Double-click to add a new folder to the game list</source>
<translation>連點兩下以新增資料夾至遊戲清單</translation>
</message>
@@ -5213,12 +5254,12 @@ Would you like to bypass this and exit anyway?</source>
<translation><numerusform>%1 / %n 個結果</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="804"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="814"/>
<source>Filter:</source>
<translation>搜尋:</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list.cpp" line="805"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="815"/>
<source>Enter pattern to filter</source>
<translation>輸入文字以搜尋</translation>
</message>
@@ -5336,6 +5377,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="137"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="138"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Main Window</source>
<translation>主要視窗</translation>
</message>
@@ -5441,6 +5483,11 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/configuration/config.cpp" line="139"/>
+ <source>Toggle Renderdoc Capture</source>
+ <translation>切换到 Renderdoc 捕获截图</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="140"/>
<source>Toggle Status Bar</source>
<translation>切換狀態列</translation>
</message>
@@ -5678,186 +5725,216 @@ Debug Message: </source>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="142"/>
+ <source>&amp;Amiibo</source>
+ <translation>Amiibo (&amp;A)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="151"/>
<source>&amp;TAS</source>
<translation>TAS (&amp;T)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="160"/>
+ <location filename="../../src/yuzu/main.ui" line="171"/>
<source>&amp;Help</source>
<translation>說明 (&amp;H)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="181"/>
+ <location filename="../../src/yuzu/main.ui" line="192"/>
<source>&amp;Install Files to NAND...</source>
<translation>&amp;安裝檔案至內部儲存空間</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="186"/>
+ <location filename="../../src/yuzu/main.ui" line="197"/>
<source>L&amp;oad File...</source>
<translation>開啟檔案(&amp;O)...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="191"/>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
<source>Load &amp;Folder...</source>
<translation>開啟資料夾(&amp;F)...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="196"/>
+ <location filename="../../src/yuzu/main.ui" line="207"/>
<source>E&amp;xit</source>
<translation>結束(&amp;X)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="204"/>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
<source>&amp;Pause</source>
<translation>暫停(&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="212"/>
+ <location filename="../../src/yuzu/main.ui" line="223"/>
<source>&amp;Stop</source>
<translation>停止(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="217"/>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
<source>&amp;Reinitialize keys...</source>
<translation>重新初始化金鑰(&amp;R)...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="222"/>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
<source>&amp;Verify Installed Contents</source>
<translation>验证已安装内容的完整性 (&amp;V)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="227"/>
+ <location filename="../../src/yuzu/main.ui" line="238"/>
<source>&amp;About yuzu</source>
<translation>關於 yuzu(&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="235"/>
+ <location filename="../../src/yuzu/main.ui" line="246"/>
<source>Single &amp;Window Mode</source>
<translation>單一視窗模式(&amp;W)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="240"/>
+ <location filename="../../src/yuzu/main.ui" line="251"/>
<source>Con&amp;figure...</source>
<translation>設定 (&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="251"/>
+ <location filename="../../src/yuzu/main.ui" line="262"/>
<source>Display D&amp;ock Widget Headers</source>
<translation>顯示 Dock 小工具標題 (&amp;O)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="259"/>
+ <location filename="../../src/yuzu/main.ui" line="270"/>
<source>Show &amp;Filter Bar</source>
<translation>顯示搜尋列(&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="267"/>
+ <location filename="../../src/yuzu/main.ui" line="278"/>
<source>Show &amp;Status Bar</source>
<translation>顯示狀態列(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="270"/>
+ <location filename="../../src/yuzu/main.ui" line="281"/>
<source>Show Status Bar</source>
<translation>顯示狀態列</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="278"/>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
<source>&amp;Browse Public Game Lobby</source>
<translation>瀏覽公用遊戲大廳 (&amp;B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="286"/>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
<source>&amp;Create Room</source>
<translation>建立房間 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="294"/>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
<source>&amp;Leave Room</source>
<translation>離開房間 (&amp;L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="299"/>
+ <location filename="../../src/yuzu/main.ui" line="310"/>
<source>&amp;Direct Connect to Room</source>
<translation>直接連線到房間 (&amp;D)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="307"/>
+ <location filename="../../src/yuzu/main.ui" line="318"/>
<source>&amp;Show Current Room</source>
<translation>顯示目前的房間 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="315"/>
+ <location filename="../../src/yuzu/main.ui" line="326"/>
<source>F&amp;ullscreen</source>
<translation>全螢幕(&amp;U)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="323"/>
+ <location filename="../../src/yuzu/main.ui" line="334"/>
<source>&amp;Restart</source>
<translation>重新啟動(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="331"/>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
<source>Load/Remove &amp;Amiibo...</source>
<translation>載入/移除 Amiibo... (&amp;A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="339"/>
+ <location filename="../../src/yuzu/main.ui" line="350"/>
<source>&amp;Report Compatibility</source>
<translation>回報相容性(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="347"/>
+ <location filename="../../src/yuzu/main.ui" line="358"/>
<source>Open &amp;Mods Page</source>
<translation>模組資訊 (&amp;M)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="352"/>
+ <location filename="../../src/yuzu/main.ui" line="363"/>
<source>Open &amp;Quickstart Guide</source>
<translation>快速入門 (&amp;Q)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="357"/>
+ <location filename="../../src/yuzu/main.ui" line="368"/>
<source>&amp;FAQ</source>
<translation>常見問題 (&amp;F)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="362"/>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
<source>Open &amp;yuzu Folder</source>
<translation>開啟 yuzu 資料夾(&amp;Y)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="370"/>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
<source>&amp;Capture Screenshot</source>
<translation>截圖 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="375"/>
+ <location filename="../../src/yuzu/main.ui" line="386"/>
+ <source>Open &amp;Album</source>
+ <translation>打开相册 (&amp;A)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="391"/>
+ <source>&amp;Set Nickname and Owner</source>
+ <translation>设置昵称及所有者 (&amp;S)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="396"/>
+ <source>&amp;Delete Game Data</source>
+ <translation>删除游戏数据 (&amp;D)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="401"/>
+ <source>&amp;Restore Amiibo</source>
+ <translation>重置 Amiibo (&amp;R)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="406"/>
+ <source>&amp;Format Amiibo</source>
+ <translation>格式化 Amiibo (&amp;F)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="411"/>
<source>Open &amp;Mii Editor</source>
<translation>打开 Mii Editor (&amp;M)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="380"/>
+ <location filename="../../src/yuzu/main.ui" line="416"/>
<source>&amp;Configure TAS...</source>
<translation>設定 &amp;TAS…</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="391"/>
+ <location filename="../../src/yuzu/main.ui" line="427"/>
<source>Configure C&amp;urrent Game...</source>
<translation>目前遊戲設定...(&amp;U)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="402"/>
+ <location filename="../../src/yuzu/main.ui" line="438"/>
<source>&amp;Start</source>
<translation>開始(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="410"/>
+ <location filename="../../src/yuzu/main.ui" line="446"/>
<source>&amp;Reset</source>
<translation>重設 (&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.ui" line="418"/>
+ <location filename="../../src/yuzu/main.ui" line="454"/>
<source>R&amp;ecord</source>
<translation>錄製 (&amp;E)</translation>
</message>
@@ -6165,27 +6242,27 @@ p, li { white-space: pre-wrap; }
<translation>不在玩游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="244"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="270"/>
<source>Installed SD Titles</source>
<translation>安裝在 SD 卡中的遊戲</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="252"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="278"/>
<source>Installed NAND Titles</source>
<translation>安裝在內部儲存空間中的遊戲</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="260"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="286"/>
<source>System Titles</source>
<translation>系統項目</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="303"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="329"/>
<source>Add New Game Directory</source>
<translation>加入遊戲資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/game_list_p.h" line="326"/>
+ <location filename="../../src/yuzu/game_list_p.h" line="352"/>
<source>Favorites</source>
<translation>我的最愛</translation>
</message>
@@ -6711,7 +6788,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="466"/>
<source>Pro Controller</source>
<translation>Pro 手把</translation>
</message>
@@ -6724,7 +6801,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="470"/>
<source>Dual Joycons</source>
<translation>雙 Joycon 手把</translation>
</message>
@@ -6737,7 +6814,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="474"/>
<source>Left Joycon</source>
<translation>左 Joycon 手把</translation>
</message>
@@ -6750,7 +6827,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="478"/>
<source>Right Joycon</source>
<translation>右 Joycon 手把</translation>
</message>
@@ -6779,7 +6856,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
<location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="482"/>
<source>Handheld</source>
<translation>掌機模式</translation>
</message>
@@ -6895,32 +6972,37 @@ p, li { white-space: pre-wrap; }
<translation>8</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="438"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2653"/>
+ <source>Not enough controllers</source>
+ <translation>控制器数量不足</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="486"/>
<source>GameCube Controller</source>
<translation>GameCube 手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="495"/>
<source>Poke Ball Plus</source>
<translation>精靈球 PLUS</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="499"/>
<source>NES Controller</source>
<translation>NES 控制手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="503"/>
<source>SNES Controller</source>
<translation>SNES 控制手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="507"/>
<source>N64 Controller</source>
<translation>N64 控制手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/applets/qt_controller.cpp" line="463"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="511"/>
<source>Sega Genesis</source>
<translation>Mega Drive</translation>
</message>
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index be8b0b5e8..fc922c31b 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -34,11 +34,6 @@ endif()
# Glad
add_subdirectory(glad)
-# inih
-if (NOT TARGET inih::INIReader)
- add_subdirectory(inih)
-endif()
-
# mbedtls
add_subdirectory(mbedtls)
target_include_directories(mbedtls PUBLIC ./mbedtls/include)
@@ -295,3 +290,8 @@ if (YUZU_CRASH_DUMPS AND NOT TARGET libbreakpad_client)
target_link_libraries(dump_syms PRIVATE libbreakpad_client ZLIB::ZLIB)
endif()
endif()
+
+# SimpleIni
+if (NOT TARGET SimpleIni::SimpleIni)
+ add_subdirectory(simpleini)
+endif()
diff --git a/externals/inih/CMakeLists.txt b/externals/inih/CMakeLists.txt
deleted file mode 100644
index ebb60a976..000000000
--- a/externals/inih/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-FileCopyrightText: 2014 Gui Andrade <admin@archshift.com>
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-add_library(inih
- inih/ini.c
- inih/ini.h
- inih/cpp/INIReader.cpp
- inih/cpp/INIReader.h
-)
-
-create_target_directory_groups(inih)
-target_include_directories(inih INTERFACE inih/cpp)
-add_library(inih::INIReader ALIAS inih)
diff --git a/externals/inih/inih b/externals/inih/inih
deleted file mode 160000
-Subproject 9cecf0643da0846e77f64d10a126d9f48b9e05e
diff --git a/externals/simpleini b/externals/simpleini
new file mode 160000
+Subproject 382ddbb4b92c0b26aa1b32cefba2002119a5b1f
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d7f68618c..e04d2418b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -21,7 +21,7 @@ if (MSVC)
# Avoid windows.h from including some usually unused libs like winsocks.h, since this might cause some redefinition errors.
add_definitions(-DWIN32_LEAN_AND_MEAN)
- # Ensure that projects build with Unicode support.
+ # Ensure that projects are built with Unicode support.
add_definitions(-DUNICODE -D_UNICODE)
# /W4 - Level 4 warnings
@@ -54,11 +54,11 @@ if (MSVC)
/GT
# Modules
- /experimental:module- # Disable module support explicitly due to conflicts with precompiled headers
+ /experimental:module- # Explicitly disable module support due to conflicts with precompiled headers.
# External headers diagnostics
/external:anglebrackets # Treats all headers included by #include <header>, where the header file is enclosed in angle brackets (< >), as external headers
- /external:W0 # Sets the default warning level to 0 for external headers, effectively turning off warnings for external headers
+ /external:W0 # Sets the default warning level to 0 for external headers, effectively disabling warnings for them.
# Warnings
/W4
@@ -187,6 +187,7 @@ add_subdirectory(audio_core)
add_subdirectory(video_core)
add_subdirectory(network)
add_subdirectory(input_common)
+add_subdirectory(frontend_common)
add_subdirectory(shader_recompiler)
if (YUZU_ROOM)
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index ac43d84b7..5721327e7 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -47,6 +47,10 @@ android {
jniLibs.useLegacyPackaging = true
}
+ androidResources {
+ generateLocaleConfig = true
+ }
+
defaultConfig {
// TODO If this is ever modified, change application_id in strings.xml
applicationId = "org.yuzu.yuzu_emu"
@@ -215,7 +219,6 @@ dependencies {
implementation("io.coil-kt:coil:2.2.2")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.window:window:1.2.0-beta03")
- implementation("org.ini4j:ini4j:0.5.4")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.4")
diff --git a/src/android/app/src/main/AndroidManifest.xml b/src/android/app/src/main/AndroidManifest.xml
index a67351727..f10131b24 100644
--- a/src/android/app/src/main/AndroidManifest.xml
+++ b/src/android/app/src/main/AndroidManifest.xml
@@ -26,7 +26,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
android:supportsRtl="true"
android:isGame="true"
android:appCategory="game"
- android:localeConfig="@xml/locales_config"
android:banner="@drawable/tv_banner"
android:fullBackupContent="@xml/data_extraction_rules"
android:dataExtractionRules="@xml/data_extraction_rules_api_31"
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
index 07f1b4842..f2ba2504c 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
@@ -230,8 +230,6 @@ object NativeLibrary {
*/
external fun onTouchReleased(finger_id: Int)
- external fun reloadSettings()
-
external fun initGameIni(gameID: String?)
external fun setAppDirectory(directory: String)
@@ -252,7 +250,7 @@ object NativeLibrary {
external fun reloadKeys(): Boolean
- external fun initializeSystem()
+ external fun initializeSystem(reload: Boolean)
external fun defaultCPUCore(): Int
@@ -462,12 +460,12 @@ object NativeLibrary {
}
fun setEmulationActivity(emulationActivity: EmulationActivity?) {
- Log.verbose("[NativeLibrary] Registering EmulationActivity.")
+ Log.debug("[NativeLibrary] Registering EmulationActivity.")
sEmulationActivity = WeakReference(emulationActivity)
}
fun clearEmulationActivity() {
- Log.verbose("[NativeLibrary] Unregistering EmulationActivity.")
+ Log.debug("[NativeLibrary] Unregistering EmulationActivity.")
sEmulationActivity.clear()
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
index 8c053670c..d114bd53d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
@@ -11,6 +11,7 @@ import java.io.File
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
import org.yuzu.yuzu_emu.utils.DocumentsTree
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
+import org.yuzu.yuzu_emu.utils.Log
fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
@@ -49,6 +50,7 @@ class YuzuApplication : Application() {
DirectoryInitialization.start()
GpuDriverHelper.initializeDriverParameters()
NativeLibrary.logDeviceInfo()
+ Log.logDeviceInfo()
createNotificationChannels()
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
index f37875ffe..f41d7bdbf 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
@@ -47,6 +47,7 @@ import org.yuzu.yuzu_emu.model.EmulationViewModel
import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.utils.ForegroundService
import org.yuzu.yuzu_emu.utils.InputHandler
+import org.yuzu.yuzu_emu.utils.Log
import org.yuzu.yuzu_emu.utils.MemoryUtil
import org.yuzu.yuzu_emu.utils.NfcReader
import org.yuzu.yuzu_emu.utils.ThemeHelper
@@ -80,6 +81,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
}
override fun onCreate(savedInstanceState: Bundle?) {
+ Log.gameLaunched = true
ThemeHelper.setTheme(this)
super.onCreate(savedInstanceState)
@@ -105,7 +107,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) {
- if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.Gb)) {
+ if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.totalMemory)) {
Toast.makeText(
this,
getString(
@@ -371,8 +373,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ val isEmulationActive = emulationViewModel.emulationStarted.value &&
+ !emulationViewModel.isEmulationStopping.value
pictureInPictureParamsBuilder.setAutoEnterEnabled(
- BooleanSetting.PICTURE_IN_PICTURE.boolean
+ BooleanSetting.PICTURE_IN_PICTURE.boolean && isEmulationActive
)
}
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
index 0c82cdba8..2ef638559 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
@@ -22,12 +22,16 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
@@ -92,28 +96,34 @@ class GameAdapter(private val activity: AppCompatActivity) :
data = Uri.parse(holder.game.path)
}
- val layerDrawable = ResourcesCompat.getDrawable(
- YuzuApplication.appContext.resources,
- R.drawable.shortcut,
- null
- ) as LayerDrawable
- layerDrawable.setDrawableByLayerId(
- R.id.shortcut_foreground,
- GameIconUtils.getGameIcon(holder.game).toDrawable(YuzuApplication.appContext.resources)
- )
- val inset = YuzuApplication.appContext.resources
- .getDimensionPixelSize(R.dimen.icon_inset)
- layerDrawable.setLayerInset(1, inset, inset, inset, inset)
- val shortcut = ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
- .setShortLabel(holder.game.title)
- .setIcon(
- IconCompat.createWithAdaptiveBitmap(
- layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
+ activity.lifecycleScope.launch {
+ withContext(Dispatchers.IO) {
+ val layerDrawable = ResourcesCompat.getDrawable(
+ YuzuApplication.appContext.resources,
+ R.drawable.shortcut,
+ null
+ ) as LayerDrawable
+ layerDrawable.setDrawableByLayerId(
+ R.id.shortcut_foreground,
+ GameIconUtils.getGameIcon(activity, holder.game)
+ .toDrawable(YuzuApplication.appContext.resources)
)
- )
- .setIntent(openIntent)
- .build()
- ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
+ val inset = YuzuApplication.appContext.resources
+ .getDimensionPixelSize(R.dimen.icon_inset)
+ layerDrawable.setLayerInset(1, inset, inset, inset, inset)
+ val shortcut =
+ ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
+ .setShortLabel(holder.game.title)
+ .setIcon(
+ IconCompat.createWithAdaptiveBitmap(
+ layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
+ )
+ )
+ .setIntent(openIntent)
+ .build()
+ ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
+ }
+ }
val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game)
view.findNavController().navigate(action)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
index 08e2a973d..d005c656e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
@@ -7,7 +7,7 @@ import android.text.TextUtils
import android.widget.Toast
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
-import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
+import org.yuzu.yuzu_emu.utils.NativeConfig
object Settings {
private val context get() = YuzuApplication.appContext
@@ -19,7 +19,7 @@ object Settings {
context.getString(R.string.ini_saved),
Toast.LENGTH_SHORT
).show()
- SettingsFile.saveFile(SettingsFile.FILE_NAME_CONFIG)
+ NativeConfig.saveSettings()
} else {
// TODO: Save custom game settings
Toast.makeText(
@@ -82,7 +82,6 @@ object Settings {
enum class MenuTag(val titleId: Int) {
SECTION_ROOT(R.string.advanced_settings),
- SECTION_GENERAL(R.string.preferences_general),
SECTION_SYSTEM(R.string.preferences_system),
SECTION_RENDERER(R.string.preferences_graphics),
SECTION_AUDIO(R.string.preferences_audio),
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt
index 522cc49df..425160024 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt
@@ -3,10 +3,13 @@
package org.yuzu.yuzu_emu.features.settings.model.view
+import androidx.annotation.DrawableRes
+
class RunnableSetting(
titleId: Int,
descriptionId: Int,
val isRuntimeRunnable: Boolean,
+ @DrawableRes val iconId: Int = 0,
val runnable: () -> Unit
) : SettingsItem(emptySetting, titleId, descriptionId) {
override val type = TYPE_RUNNABLE
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
index b3b3fc209..6aba69dbe 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
@@ -73,7 +73,7 @@ abstract class SettingsItem(
R.string.frame_limit_slider,
R.string.frame_limit_slider_description,
1,
- 200,
+ 400,
"%"
)
)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt
index b343e527e..94953b18a 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt
@@ -3,11 +3,14 @@
package org.yuzu.yuzu_emu.features.settings.model.view
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
import org.yuzu.yuzu_emu.features.settings.model.Settings
class SubmenuSetting(
- titleId: Int,
- descriptionId: Int,
+ @StringRes titleId: Int,
+ @StringRes descriptionId: Int,
+ @DrawableRes val iconId: Int,
val menuKey: Settings.MenuTag
) : SettingsItem(emptySetting, titleId, descriptionId) {
override val type = TYPE_SUBMENU
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
index c73edd50e..48bdbdd75 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
@@ -21,7 +21,6 @@ import androidx.navigation.navArgs
import com.google.android.material.color.MaterialColors
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
-import org.yuzu.yuzu_emu.NativeLibrary
import java.io.IOException
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding
@@ -165,11 +164,12 @@ class SettingsActivity : AppCompatActivity() {
settingsViewModel.shouldSave = false
// Delete settings file because the user may have changed values that do not exist in the UI
+ NativeConfig.unloadConfig()
val settingsFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_CONFIG)
if (!settingsFile.delete()) {
throw IOException("Failed to delete $settingsFile")
}
- NativeLibrary.reloadSettings()
+ NativeConfig.initializeConfig()
Toast.makeText(
applicationContext,
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
index 70d8ec14b..769baf744 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
@@ -20,7 +20,6 @@ import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
-import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.transition.MaterialSharedAxis
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -68,15 +67,9 @@ class SettingsFragment : Fragment() {
)
binding.toolbarSettingsLayout.title = getString(args.menuTag.titleId)
- val dividerDecoration = MaterialDividerItemDecoration(
- requireContext(),
- LinearLayoutManager.VERTICAL
- )
- dividerDecoration.isLastItemDecorated = false
binding.listSettings.apply {
adapter = settingsAdapter
layoutManager = LinearLayoutManager(requireContext())
- addItemDecoration(dividerDecoration)
}
binding.toolbarSettings.setNavigationOnClickListener {
@@ -94,17 +87,6 @@ class SettingsFragment : Fragment() {
}
}
}
- launch {
- settingsViewModel.isUsingSearch.collectLatest {
- if (it) {
- reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
- exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
- } else {
- reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
- exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
- }
- }
- }
}
if (args.menuTag == Settings.MenuTag.SECTION_ROOT) {
@@ -112,8 +94,6 @@ class SettingsFragment : Fragment() {
binding.toolbarSettings.setOnMenuItemClickListener {
when (it.itemId) {
R.id.action_search -> {
- reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
- exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
view.findNavController()
.navigate(R.id.action_settingsFragment_to_settingsSearchFragment)
true
@@ -129,11 +109,6 @@ class SettingsFragment : Fragment() {
setInsets()
}
- override fun onResume() {
- super.onResume()
- settingsViewModel.setIsUsingSearch(false)
- }
-
private fun setInsets() {
ViewCompat.setOnApplyWindowInsetsListener(
binding.root
@@ -144,10 +119,9 @@ class SettingsFragment : Fragment() {
val leftInsets = barInsets.left + cutoutInsets.left
val rightInsets = barInsets.right + cutoutInsets.right
- val sideMargin = resources.getDimensionPixelSize(R.dimen.spacing_medlarge)
val mlpSettingsList = binding.listSettings.layoutParams as MarginLayoutParams
- mlpSettingsList.leftMargin = sideMargin + leftInsets
- mlpSettingsList.rightMargin = sideMargin + rightInsets
+ mlpSettingsList.leftMargin = leftInsets
+ mlpSettingsList.rightMargin = rightInsets
binding.listSettings.layoutParams = mlpSettingsList
binding.listSettings.updatePadding(
bottom = barInsets.bottom
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index 766414a6c..8b71e32f3 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -3,7 +3,6 @@
package org.yuzu.yuzu_emu.features.settings.ui
-import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.widget.Toast
@@ -32,8 +31,6 @@ class SettingsFragmentPresenter(
private val preferences: SharedPreferences
get() = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
- private val context: Context get() = YuzuApplication.appContext
-
// Extension for populating settings list based on paired settings
fun ArrayList<SettingsItem>.add(key: String) {
val item = SettingsItem.settingsItems[key]!!
@@ -53,7 +50,6 @@ class SettingsFragmentPresenter(
val sl = ArrayList<SettingsItem>()
when (menuTag) {
Settings.MenuTag.SECTION_ROOT -> addConfigSettings(sl)
- Settings.MenuTag.SECTION_GENERAL -> addGeneralSettings(sl)
Settings.MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
Settings.MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
Settings.MenuTag.SECTION_AUDIO -> addAudioSettings(sl)
@@ -75,30 +71,53 @@ class SettingsFragmentPresenter(
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
- add(SubmenuSetting(R.string.preferences_general, 0, Settings.MenuTag.SECTION_GENERAL))
- add(SubmenuSetting(R.string.preferences_system, 0, Settings.MenuTag.SECTION_SYSTEM))
- add(SubmenuSetting(R.string.preferences_graphics, 0, Settings.MenuTag.SECTION_RENDERER))
- add(SubmenuSetting(R.string.preferences_audio, 0, Settings.MenuTag.SECTION_AUDIO))
- add(SubmenuSetting(R.string.preferences_debug, 0, Settings.MenuTag.SECTION_DEBUG))
add(
- RunnableSetting(R.string.reset_to_default, 0, false) {
- settingsViewModel.setShouldShowResetSettingsDialog(true)
- }
+ SubmenuSetting(
+ R.string.preferences_system,
+ R.string.preferences_system_description,
+ R.drawable.ic_system_settings,
+ Settings.MenuTag.SECTION_SYSTEM
+ )
+ )
+ add(
+ SubmenuSetting(
+ R.string.preferences_graphics,
+ R.string.preferences_graphics_description,
+ R.drawable.ic_graphics,
+ Settings.MenuTag.SECTION_RENDERER
+ )
+ )
+ add(
+ SubmenuSetting(
+ R.string.preferences_audio,
+ R.string.preferences_audio_description,
+ R.drawable.ic_audio,
+ Settings.MenuTag.SECTION_AUDIO
+ )
+ )
+ add(
+ SubmenuSetting(
+ R.string.preferences_debug,
+ R.string.preferences_debug_description,
+ R.drawable.ic_code,
+ Settings.MenuTag.SECTION_DEBUG
+ )
+ )
+ add(
+ RunnableSetting(
+ R.string.reset_to_default,
+ R.string.reset_to_default_description,
+ false,
+ R.drawable.ic_restore
+ ) { settingsViewModel.setShouldShowResetSettingsDialog(true) }
)
}
}
- private fun addGeneralSettings(sl: ArrayList<SettingsItem>) {
+ private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
add(ShortSetting.RENDERER_SPEED_LIMIT.key)
- add(IntSetting.CPU_ACCURACY.key)
- add(BooleanSetting.PICTURE_IN_PICTURE.key)
- }
- }
-
- private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
- sl.apply {
add(BooleanSetting.USE_DOCKED_MODE.key)
add(IntSetting.REGION_INDEX.key)
add(IntSetting.LANGUAGE_INDEX.key)
@@ -116,6 +135,7 @@ class SettingsFragmentPresenter(
add(IntSetting.RENDERER_ANTI_ALIASING.key)
add(IntSetting.RENDERER_SCREEN_LAYOUT.key)
add(IntSetting.RENDERER_ASPECT_RATIO.key)
+ add(BooleanSetting.PICTURE_IN_PICTURE.key)
add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
@@ -249,6 +269,7 @@ class SettingsFragmentPresenter(
add(BooleanSetting.RENDERER_DEBUG.key)
add(HeaderSetting(R.string.cpu))
+ add(IntSetting.CPU_ACCURACY.key)
add(BooleanSetting.CPU_DEBUG_MODE.key)
add(SettingsItem.FASTMEM_COMBINED)
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt
index 83a2e94f1..036195624 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt
@@ -4,6 +4,7 @@
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
import android.view.View
+import androidx.core.content.res.ResourcesCompat
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.RunnableSetting
@@ -16,6 +17,19 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
override fun bind(item: SettingsItem) {
setting = item as RunnableSetting
+ if (item.iconId != 0) {
+ binding.icon.visibility = View.VISIBLE
+ binding.icon.setImageDrawable(
+ ResourcesCompat.getDrawable(
+ binding.icon.resources,
+ item.iconId,
+ binding.icon.context.theme
+ )
+ )
+ } else {
+ binding.icon.visibility = View.GONE
+ }
+
binding.textSettingName.setText(item.nameId)
if (item.descriptionId != 0) {
binding.textSettingDescription.setText(item.descriptionId)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
index 1cf581a9d..8100c65dd 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
@@ -4,6 +4,7 @@
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
import android.view.View
+import androidx.core.content.res.ResourcesCompat
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting
@@ -15,6 +16,19 @@ class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAd
override fun bind(item: SettingsItem) {
this.item = item as SubmenuSetting
+ if (item.iconId != 0) {
+ binding.icon.visibility = View.VISIBLE
+ binding.icon.setImageDrawable(
+ ResourcesCompat.getDrawable(
+ binding.icon.resources,
+ item.iconId,
+ binding.icon.context.theme
+ )
+ )
+ } else {
+ binding.icon.visibility = View.GONE
+ }
+
binding.textSettingName.setText(item.nameId)
if (item.descriptionId != 0) {
binding.textSettingDescription.setText(item.descriptionId)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
index 2b04d666a..3ae5b4653 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
@@ -3,15 +3,8 @@
package org.yuzu.yuzu_emu.features.settings.utils
-import android.widget.Toast
import java.io.*
-import org.ini4j.Wini
-import org.yuzu.yuzu_emu.R
-import org.yuzu.yuzu_emu.YuzuApplication
-import org.yuzu.yuzu_emu.features.settings.model.*
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
-import org.yuzu.yuzu_emu.utils.Log
-import org.yuzu.yuzu_emu.utils.NativeConfig
/**
* Contains static methods for interacting with .ini files in which settings are stored.
@@ -19,41 +12,6 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
object SettingsFile {
const val FILE_NAME_CONFIG = "config"
- /**
- * Saves a Settings HashMap to a given .ini file on disk. If unsuccessful, outputs an error
- * telling why it failed.
- *
- * @param fileName The target filename without a path or extension.
- */
- fun saveFile(fileName: String) {
- val ini = getSettingsFile(fileName)
- try {
- val wini = Wini(ini)
- for (specificCategory in Settings.Category.values()) {
- val categoryHeader = NativeConfig.getConfigHeader(specificCategory.ordinal)
- for (setting in Settings.settingsList) {
- if (setting.key!!.isEmpty()) continue
-
- val settingCategoryHeader =
- NativeConfig.getConfigHeader(setting.category.ordinal)
- val iniSetting: String? = wini.get(categoryHeader, setting.key)
- if (iniSetting != null || settingCategoryHeader == categoryHeader) {
- wini.put(settingCategoryHeader, setting.key, setting.valueAsString)
- }
- }
- }
- wini.store()
- } catch (e: IOException) {
- Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.message)
- val context = YuzuApplication.appContext
- Toast.makeText(
- context,
- context.getString(R.string.error_saving, fileName, e.message),
- Toast.LENGTH_SHORT
- ).show()
- }
- }
-
fun getSettingsFile(fileName: String): File =
File(DirectoryInitialization.userDirectory + "/config/" + fileName + ".ini")
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
index 2ff827c6b..a1620fbb7 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
@@ -114,10 +114,10 @@ class AboutFragment : Fragment() {
val leftInsets = barInsets.left + cutoutInsets.left
val rightInsets = barInsets.right + cutoutInsets.right
- val mlpAppBar = binding.appbarAbout.layoutParams as MarginLayoutParams
- mlpAppBar.leftMargin = leftInsets
- mlpAppBar.rightMargin = rightInsets
- binding.appbarAbout.layoutParams = mlpAppBar
+ val mlpToolbar = binding.toolbarAbout.layoutParams as MarginLayoutParams
+ mlpToolbar.leftMargin = leftInsets
+ mlpToolbar.rightMargin = rightInsets
+ binding.toolbarAbout.layoutParams = mlpToolbar
val mlpScrollAbout = binding.scrollAbout.layoutParams as MarginLayoutParams
mlpScrollAbout.leftMargin = leftInsets
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index 07bd78bf7..c32fa0d7e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -10,7 +10,6 @@ import android.content.DialogInterface
import android.content.SharedPreferences
import android.content.pm.ActivityInfo
import android.content.res.Configuration
-import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
@@ -155,7 +154,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
binding.surfaceEmulation.holder.addCallback(this)
- binding.showFpsText.setTextColor(Color.YELLOW)
binding.doneControlConfig.setOnClickListener { stopConfiguringControls() }
binding.drawerLayout.addDrawerListener(object : DrawerListener {
@@ -312,6 +310,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
ViewUtils.showView(binding.surfaceInputOverlay)
ViewUtils.hideView(binding.loadingIndicator)
+ emulationState.updateSurface()
+
// Setup overlay
updateShowFpsOverlay()
}
@@ -412,12 +412,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
val FRAMETIME = 2
val SPEED = 3
perfStatsUpdater = {
- if (emulationViewModel.emulationStarted.value == true) {
+ if (emulationViewModel.emulationStarted.value) {
val perfStats = NativeLibrary.getPerfStats()
- if (perfStats[FPS] > 0 && _binding != null) {
+ if (_binding != null) {
binding.showFpsText.text = String.format("FPS: %.1f", perfStats[FPS])
}
- perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 100)
+ perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 800)
}
}
perfStatsUpdateHandler.post(perfStatsUpdater!!)
@@ -462,7 +462,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (it.orientation == FoldingFeature.Orientation.HORIZONTAL) {
// Restrict emulation and overlays to the top of the screen
binding.emulationContainer.layoutParams.height = it.bounds.top
- binding.overlayContainer.layoutParams.height = it.bounds.top
// Restrict input and menu drawer to the bottom of the screen
binding.inputContainer.layoutParams.height = it.bounds.bottom
binding.inGameMenu.layoutParams.height = it.bounds.bottom
@@ -476,7 +475,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (!isFolding) {
binding.emulationContainer.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
binding.inputContainer.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
- binding.overlayContainer.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
binding.inGameMenu.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
isInFoldableLayout = false
updateOrientation()
@@ -484,7 +482,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
binding.emulationContainer.requestLayout()
binding.inputContainer.requestLayout()
- binding.overlayContainer.requestLayout()
binding.inGameMenu.requestLayout()
}
@@ -710,24 +707,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
v.setPadding(left, cutInsets.top, right, 0)
-
- // Ensure FPS text doesn't get cut off by rounded display corners
- val sidePadding = resources.getDimensionPixelSize(R.dimen.spacing_xtralarge)
- if (cutInsets.left == 0) {
- binding.showFpsText.setPadding(
- sidePadding,
- cutInsets.top,
- cutInsets.right,
- cutInsets.bottom
- )
- } else {
- binding.showFpsText.setPadding(
- cutInsets.left,
- cutInsets.top,
- cutInsets.right,
- cutInsets.bottom
- )
- }
windowInsets
}
}
@@ -805,6 +784,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
@Synchronized
+ fun updateSurface() {
+ if (surface != null) {
+ NativeLibrary.surfaceChanged(surface)
+ }
+ }
+
+ @Synchronized
fun clearSurface() {
if (surface == null) {
Log.warning("[EmulationFragment] clearSurface called, but surface already null.")
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
index 6e19fc6c0..4720daec4 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
@@ -42,6 +42,7 @@ import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.ui.main.MainActivity
import org.yuzu.yuzu_emu.utils.FileUtil
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
+import org.yuzu.yuzu_emu.utils.Log
class HomeSettingsFragment : Fragment() {
private var _binding: FragmentHomeSettingsBinding? = null
@@ -86,28 +87,6 @@ class HomeSettingsFragment : Fragment() {
)
add(
HomeSetting(
- R.string.open_user_folder,
- R.string.open_user_folder_description,
- R.drawable.ic_folder_open,
- { openFileManager() }
- )
- )
- add(
- HomeSetting(
- R.string.preferences_theme,
- R.string.theme_and_color_description,
- R.drawable.ic_palette,
- {
- val action = HomeNavigationDirections.actionGlobalSettingsActivity(
- null,
- Settings.MenuTag.SECTION_THEME
- )
- binding.root.findNavController().navigate(action)
- }
- )
- )
- add(
- HomeSetting(
R.string.gpu_driver_manager,
R.string.install_gpu_driver_description,
R.drawable.ic_build,
@@ -123,17 +102,6 @@ class HomeSettingsFragment : Fragment() {
)
add(
HomeSetting(
- R.string.manage_yuzu_data,
- R.string.manage_yuzu_data_description,
- R.drawable.ic_install,
- {
- binding.root.findNavController()
- .navigate(R.id.action_homeSettingsFragment_to_installableFragment)
- }
- )
- )
- add(
- HomeSetting(
R.string.applets,
R.string.applets_description,
R.drawable.ic_applet,
@@ -148,6 +116,17 @@ class HomeSettingsFragment : Fragment() {
)
add(
HomeSetting(
+ R.string.manage_yuzu_data,
+ R.string.manage_yuzu_data_description,
+ R.drawable.ic_install,
+ {
+ binding.root.findNavController()
+ .navigate(R.id.action_homeSettingsFragment_to_installableFragment)
+ }
+ )
+ )
+ add(
+ HomeSetting(
R.string.select_games_folder,
R.string.select_games_folder_description,
R.drawable.ic_add,
@@ -172,6 +151,28 @@ class HomeSettingsFragment : Fragment() {
)
add(
HomeSetting(
+ R.string.open_user_folder,
+ R.string.open_user_folder_description,
+ R.drawable.ic_folder_open,
+ { openFileManager() }
+ )
+ )
+ add(
+ HomeSetting(
+ R.string.preferences_theme,
+ R.string.theme_and_color_description,
+ R.drawable.ic_palette,
+ {
+ val action = HomeNavigationDirections.actionGlobalSettingsActivity(
+ null,
+ Settings.MenuTag.SECTION_THEME
+ )
+ binding.root.findNavController().navigate(action)
+ }
+ )
+ )
+ add(
+ HomeSetting(
R.string.about,
R.string.about_description,
R.drawable.ic_info_outline,
@@ -312,19 +313,32 @@ class HomeSettingsFragment : Fragment() {
}
}
+ // Share the current log if we just returned from a game but share the old log
+ // if we just started the app and the old log exists.
private fun shareLog() {
- val file = DocumentFile.fromSingleUri(
+ val currentLog = DocumentFile.fromSingleUri(
mainActivity,
DocumentsContract.buildDocumentUri(
DocumentProvider.AUTHORITY,
"${DocumentProvider.ROOT_ID}/log/yuzu_log.txt"
)
)!!
- if (file.exists()) {
- val intent = Intent(Intent.ACTION_SEND)
- .setDataAndType(file.uri, FileUtil.TEXT_PLAIN)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- .putExtra(Intent.EXTRA_STREAM, file.uri)
+ val oldLog = DocumentFile.fromSingleUri(
+ mainActivity,
+ DocumentsContract.buildDocumentUri(
+ DocumentProvider.AUTHORITY,
+ "${DocumentProvider.ROOT_ID}/log/yuzu_log.txt.old.txt"
+ )
+ )!!
+
+ val intent = Intent(Intent.ACTION_SEND)
+ .setDataAndType(currentLog.uri, FileUtil.TEXT_PLAIN)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ if (!Log.gameLaunched && oldLog.exists()) {
+ intent.putExtra(Intent.EXTRA_STREAM, oldLog.uri)
+ startActivity(Intent.createChooser(intent, getText(R.string.share_log)))
+ } else if (currentLog.exists()) {
+ intent.putExtra(Intent.EXTRA_STREAM, currentLog.uri)
startActivity(Intent.createChooser(intent, getText(R.string.share_log)))
} else {
Toast.makeText(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
index ec116ab62..6940fc757 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
@@ -21,6 +21,8 @@ import org.yuzu.yuzu_emu.databinding.FragmentInstallablesBinding
import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.model.Installable
import org.yuzu.yuzu_emu.ui.main.MainActivity
+import java.time.LocalDateTime
+import java.time.format.DateTimeFormatter
class InstallableFragment : Fragment() {
private var _binding: FragmentInstallablesBinding? = null
@@ -78,7 +80,15 @@ class InstallableFragment : Fragment() {
R.string.manage_save_data,
R.string.import_export_saves_description,
install = { mainActivity.importSaves.launch(arrayOf("application/zip")) },
- export = { mainActivity.exportSave() }
+ export = {
+ mainActivity.exportSaves.launch(
+ "yuzu saves - ${
+ LocalDateTime.now().format(
+ DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
+ )
+ }.zip"
+ )
+ }
)
} else {
Installable(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt
index 9d0594c6e..f95d545bf 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt
@@ -40,8 +40,10 @@ class SettingsSearchFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
- returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
+ enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
+ returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
+ reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
+ exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
}
override fun onCreateView(
@@ -55,7 +57,6 @@ class SettingsSearchFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- settingsViewModel.setIsUsingSearch(true)
if (savedInstanceState != null) {
binding.searchText.setText(savedInstanceState.getString(SEARCH_TEXT))
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
index de84b2adb..2fa3ab31b 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
@@ -18,8 +18,8 @@ class Game(
val version: String = "",
val isHomebrew: Boolean = false
) : Parcelable {
- val keyAddedToLibraryTime get() = "${programId}_AddedToLibraryTime"
- val keyLastPlayedTime get() = "${programId}_LastPlayed"
+ val keyAddedToLibraryTime get() = "${path}_AddedToLibraryTime"
+ val keyLastPlayedTime get() = "${path}_LastPlayed"
override fun equals(other: Any?): Boolean {
if (other !is Game) {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
index 53fa7a8de..6f947674e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
@@ -29,9 +29,6 @@ class SettingsViewModel : ViewModel() {
val shouldReloadSettingsList: StateFlow<Boolean> get() = _shouldReloadSettingsList
private val _shouldReloadSettingsList = MutableStateFlow(false)
- val isUsingSearch: StateFlow<Boolean> get() = _isUsingSearch
- private val _isUsingSearch = MutableStateFlow(false)
-
val sliderProgress: StateFlow<Int> get() = _sliderProgress
private val _sliderProgress = MutableStateFlow(-1)
@@ -57,10 +54,6 @@ class SettingsViewModel : ViewModel() {
_shouldReloadSettingsList.value = value
}
- fun setIsUsingSearch(value: Boolean) {
- _isUsingSearch.value = value
- }
-
fun setSliderTextValue(value: Float, units: String) {
_sliderProgress.value = value.toInt()
_sliderTextValue.value = String.format(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index ba1177426..bd2f4cd25 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -6,7 +6,6 @@ package org.yuzu.yuzu_emu.ui.main
import android.content.Intent
import android.net.Uri
import android.os.Bundle
-import android.provider.DocumentsContract
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.view.WindowManager
@@ -20,7 +19,6 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
-import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
@@ -41,7 +39,6 @@ import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.activities.EmulationActivity
import org.yuzu.yuzu_emu.databinding.ActivityMainBinding
-import org.yuzu.yuzu_emu.features.DocumentProvider
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.fragments.IndeterminateProgressDialogFragment
import org.yuzu.yuzu_emu.fragments.MessageDialogFragment
@@ -53,9 +50,6 @@ import org.yuzu.yuzu_emu.model.TaskViewModel
import org.yuzu.yuzu_emu.utils.*
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
-import java.io.FileOutputStream
-import java.time.LocalDateTime
-import java.time.format.DateTimeFormatter
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
@@ -73,7 +67,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
// Get first subfolder in saves folder (should be the user folder)
val savesFolderRoot get() = File(savesFolder).listFiles()?.firstOrNull()?.canonicalPath ?: ""
- private var lastZipCreated: File? = null
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
@@ -403,7 +396,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
} else {
firmwarePath.deleteRecursively()
cacheFirmwareDir.copyRecursively(firmwarePath, true)
- NativeLibrary.initializeSystem()
+ NativeLibrary.initializeSystem(true)
getString(R.string.save_file_imported_success)
}
} catch (e: Exception) {
@@ -632,6 +625,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
}
// Clear existing user data
+ NativeConfig.unloadConfig()
File(DirectoryInitialization.userDirectory!!).deleteRecursively()
// Copy archive to internal storage
@@ -649,7 +643,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
}
// Reinitialize relevant data
- NativeLibrary.initializeSystem()
+ NativeLibrary.initializeSystem(true)
+ NativeConfig.initializeConfig()
gamesViewModel.reloadGames(false)
return@newInstance getString(R.string.user_data_import_success)
@@ -657,74 +652,30 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
}
/**
- * Zips the save files located in the given folder path and creates a new zip file with the current date and time.
- * @return true if the zip file is successfully created, false otherwise.
- */
- private fun zipSave(): Boolean {
- try {
- val tempFolder = File(getPublicFilesDir().canonicalPath, "temp")
- tempFolder.mkdirs()
- val saveFolder = File(savesFolderRoot)
- val outputZipFile = File(
- tempFolder,
- "yuzu saves - ${
- LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
- }.zip"
- )
- outputZipFile.createNewFile()
- val result = FileUtil.zipFromInternalStorage(
- saveFolder,
- savesFolderRoot,
- BufferedOutputStream(FileOutputStream(outputZipFile))
- )
- if (result == TaskState.Failed) {
- return false
- }
- lastZipCreated = outputZipFile
- } catch (e: Exception) {
- return false
- }
- return true
- }
-
- /**
* Exports the save file located in the given folder path by creating a zip file and sharing it via intent.
*/
- fun exportSave() {
- CoroutineScope(Dispatchers.IO).launch {
- val wasZipCreated = zipSave()
- val lastZipFile = lastZipCreated
- if (!wasZipCreated || lastZipFile == null) {
- withContext(Dispatchers.Main) {
- Toast.makeText(
- this@MainActivity,
- getString(R.string.export_save_failed),
- Toast.LENGTH_LONG
- ).show()
- }
- return@launch
- }
+ val exportSaves = registerForActivityResult(
+ ActivityResultContracts.CreateDocument("application/zip")
+ ) { result ->
+ if (result == null) {
+ return@registerForActivityResult
+ }
- withContext(Dispatchers.Main) {
- val file = DocumentFile.fromSingleUri(
- this@MainActivity,
- DocumentsContract.buildDocumentUri(
- DocumentProvider.AUTHORITY,
- "${DocumentProvider.ROOT_ID}/temp/${lastZipFile.name}"
- )
- )!!
- val intent = Intent(Intent.ACTION_SEND)
- .setDataAndType(file.uri, "application/zip")
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- .putExtra(Intent.EXTRA_STREAM, file.uri)
- startForResultExportSave.launch(
- Intent.createChooser(
- intent,
- getString(R.string.share_save_file)
- )
- )
+ IndeterminateProgressDialogFragment.newInstance(
+ this,
+ R.string.save_files_exporting,
+ false
+ ) {
+ val zipResult = FileUtil.zipFromInternalStorage(
+ File(savesFolderRoot),
+ savesFolderRoot,
+ BufferedOutputStream(contentResolver.openOutputStream(result))
+ )
+ return@newInstance when (zipResult) {
+ TaskState.Completed -> getString(R.string.export_success)
+ TaskState.Cancelled, TaskState.Failed -> getString(R.string.export_failed)
}
- }
+ }.show(supportFragmentManager, IndeterminateProgressDialogFragment.TAG)
}
private val startForResultExportSave =
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
index 79a07f7ef..21270fc84 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
@@ -15,7 +15,8 @@ object DirectoryInitialization {
fun start() {
if (!areDirectoriesReady) {
initializeInternalStorage()
- NativeLibrary.initializeSystem()
+ NativeLibrary.initializeSystem(false)
+ NativeConfig.initializeConfig()
areDirectoriesReady = true
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
index 654d62f52..2e9b0beb8 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
@@ -8,9 +8,9 @@ import android.graphics.BitmapFactory
import android.widget.ImageView
import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
+import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader
import coil.decode.DataSource
-import coil.executeBlocking
import coil.fetch.DrawableResult
import coil.fetch.FetchResult
import coil.fetch.Fetcher
@@ -76,12 +76,13 @@ object GameIconUtils {
imageLoader.enqueue(request)
}
- fun getGameIcon(game: Game): Bitmap {
+ suspend fun getGameIcon(lifecycleOwner: LifecycleOwner, game: Game): Bitmap {
val request = ImageRequest.Builder(YuzuApplication.appContext)
.data(game)
+ .lifecycle(lifecycleOwner)
.error(R.drawable.default_icon)
.build()
- return imageLoader.executeBlocking(request)
+ return imageLoader.execute(request)
.drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888)
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt
index fc6a8b5cb..e63382e1d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt
@@ -27,6 +27,8 @@ object InputHandler {
0x054C -> getInputDS5ButtonKey(event.keyCode)
0x057E -> getInputJoyconButtonKey(event.keyCode)
0x1532 -> getInputRazerButtonKey(event.keyCode)
+ 0x3537 -> getInputRedmagicButtonKey(event.keyCode)
+ 0x358A -> getInputBackboneLabsButtonKey(event.keyCode)
else -> getInputGenericButtonKey(event.keyCode)
}
@@ -68,7 +70,7 @@ object InputHandler {
private fun getPlayerNumber(index: Int, deviceId: Int = -1): Int {
var deviceIndex = index
if (deviceId != -1) {
- deviceIndex = controllerIds[deviceId]!!
+ deviceIndex = controllerIds[deviceId] ?: 0
}
// TODO: Joycons are handled as different controllers. Find a way to merge them.
@@ -227,6 +229,42 @@ object InputHandler {
}
}
+ private fun getInputRedmagicButtonKey(key: Int): Int {
+ return when (key) {
+ KeyEvent.KEYCODE_BUTTON_A -> NativeLibrary.ButtonType.BUTTON_B
+ KeyEvent.KEYCODE_BUTTON_B -> NativeLibrary.ButtonType.BUTTON_A
+ KeyEvent.KEYCODE_BUTTON_X -> NativeLibrary.ButtonType.BUTTON_Y
+ KeyEvent.KEYCODE_BUTTON_Y -> NativeLibrary.ButtonType.BUTTON_X
+ KeyEvent.KEYCODE_BUTTON_L1 -> NativeLibrary.ButtonType.TRIGGER_L
+ KeyEvent.KEYCODE_BUTTON_R1 -> NativeLibrary.ButtonType.TRIGGER_R
+ KeyEvent.KEYCODE_BUTTON_L2 -> NativeLibrary.ButtonType.TRIGGER_ZL
+ KeyEvent.KEYCODE_BUTTON_R2 -> NativeLibrary.ButtonType.TRIGGER_ZR
+ KeyEvent.KEYCODE_BUTTON_THUMBL -> NativeLibrary.ButtonType.STICK_L
+ KeyEvent.KEYCODE_BUTTON_THUMBR -> NativeLibrary.ButtonType.STICK_R
+ KeyEvent.KEYCODE_BUTTON_START -> NativeLibrary.ButtonType.BUTTON_PLUS
+ KeyEvent.KEYCODE_BUTTON_SELECT -> NativeLibrary.ButtonType.BUTTON_MINUS
+ else -> -1
+ }
+ }
+
+ private fun getInputBackboneLabsButtonKey(key: Int): Int {
+ return when (key) {
+ KeyEvent.KEYCODE_BUTTON_A -> NativeLibrary.ButtonType.BUTTON_B
+ KeyEvent.KEYCODE_BUTTON_B -> NativeLibrary.ButtonType.BUTTON_A
+ KeyEvent.KEYCODE_BUTTON_X -> NativeLibrary.ButtonType.BUTTON_Y
+ KeyEvent.KEYCODE_BUTTON_Y -> NativeLibrary.ButtonType.BUTTON_X
+ KeyEvent.KEYCODE_BUTTON_L1 -> NativeLibrary.ButtonType.TRIGGER_L
+ KeyEvent.KEYCODE_BUTTON_R1 -> NativeLibrary.ButtonType.TRIGGER_R
+ KeyEvent.KEYCODE_BUTTON_L2 -> NativeLibrary.ButtonType.TRIGGER_ZL
+ KeyEvent.KEYCODE_BUTTON_R2 -> NativeLibrary.ButtonType.TRIGGER_ZR
+ KeyEvent.KEYCODE_BUTTON_THUMBL -> NativeLibrary.ButtonType.STICK_L
+ KeyEvent.KEYCODE_BUTTON_THUMBR -> NativeLibrary.ButtonType.STICK_R
+ KeyEvent.KEYCODE_BUTTON_START -> NativeLibrary.ButtonType.BUTTON_PLUS
+ KeyEvent.KEYCODE_BUTTON_SELECT -> NativeLibrary.ButtonType.BUTTON_MINUS
+ else -> -1
+ }
+ }
+
private fun getInputGenericButtonKey(key: Int): Int {
return when (key) {
KeyEvent.KEYCODE_BUTTON_A -> NativeLibrary.ButtonType.BUTTON_A
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt
index a193e82a4..aebe84b0f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/Log.kt
@@ -3,38 +3,29 @@
package org.yuzu.yuzu_emu.utils
-import android.util.Log
-import org.yuzu.yuzu_emu.BuildConfig
-
-/**
- * Contains methods that call through to [android.util.Log], but
- * with the same TAG automatically provided. Also no-ops VERBOSE and DEBUG log
- * levels in release builds.
- */
+import android.os.Build
+
object Log {
- private const val TAG = "Yuzu Frontend"
+ // Tracks whether we should share the old log or the current log
+ var gameLaunched = false
- fun verbose(message: String) {
- if (BuildConfig.DEBUG) {
- Log.v(TAG, message)
- }
- }
+ external fun debug(message: String)
- fun debug(message: String) {
- if (BuildConfig.DEBUG) {
- Log.d(TAG, message)
- }
- }
+ external fun warning(message: String)
- fun info(message: String) {
- Log.i(TAG, message)
- }
+ external fun info(message: String)
- fun warning(message: String) {
- Log.w(TAG, message)
- }
+ external fun error(message: String)
- fun error(message: String) {
- Log.e(TAG, message)
+ external fun critical(message: String)
+
+ fun logDeviceInfo() {
+ info("Device Manufacturer - ${Build.MANUFACTURER}")
+ info("Device Model - ${Build.MODEL}")
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+ info("SoC Manufacturer - ${Build.SOC_MANUFACTURER}")
+ info("SoC Model - ${Build.SOC_MODEL}")
+ }
+ info("Total System Memory - ${MemoryUtil.getDeviceRAM()}")
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt
index aa4a5539a..9076a86c4 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/MemoryUtil.kt
@@ -27,7 +27,7 @@ object MemoryUtil {
const val Pb = Tb * 1024
const val Eb = Pb * 1024
- private fun bytesToSizeUnit(size: Float): String =
+ private fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String =
when {
size < Kb -> {
context.getString(
@@ -39,63 +39,59 @@ object MemoryUtil {
size < Mb -> {
context.getString(
R.string.memory_formatted,
- (size / Kb).hundredths,
+ if (roundUp) ceil(size / Kb) else (size / Kb).hundredths,
context.getString(R.string.memory_kilobyte)
)
}
size < Gb -> {
context.getString(
R.string.memory_formatted,
- (size / Mb).hundredths,
+ if (roundUp) ceil(size / Mb) else (size / Mb).hundredths,
context.getString(R.string.memory_megabyte)
)
}
size < Tb -> {
context.getString(
R.string.memory_formatted,
- (size / Gb).hundredths,
+ if (roundUp) ceil(size / Gb) else (size / Gb).hundredths,
context.getString(R.string.memory_gigabyte)
)
}
size < Pb -> {
context.getString(
R.string.memory_formatted,
- (size / Tb).hundredths,
+ if (roundUp) ceil(size / Tb) else (size / Tb).hundredths,
context.getString(R.string.memory_terabyte)
)
}
size < Eb -> {
context.getString(
R.string.memory_formatted,
- (size / Pb).hundredths,
+ if (roundUp) ceil(size / Pb) else (size / Pb).hundredths,
context.getString(R.string.memory_petabyte)
)
}
else -> {
context.getString(
R.string.memory_formatted,
- (size / Eb).hundredths,
+ if (roundUp) ceil(size / Eb) else (size / Eb).hundredths,
context.getString(R.string.memory_exabyte)
)
}
}
- // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for
- // the potential error created by memInfo.totalMem
- private val totalMemory: Float
+ val totalMemory: Float
get() {
val memInfo = ActivityManager.MemoryInfo()
with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) {
getMemoryInfo(memInfo)
}
- return ceil(
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
- memInfo.advertisedMem.toFloat()
- } else {
- memInfo.totalMem.toFloat()
- }
- )
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ memInfo.advertisedMem.toFloat()
+ } else {
+ memInfo.totalMem.toFloat()
+ }
}
fun isLessThan(minimum: Int, size: Float): Boolean =
@@ -109,5 +105,7 @@ object MemoryUtil {
else -> totalMemory < Kb && totalMemory < minimum
}
- fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory)
+ // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for
+ // the potential error created by memInfo.totalMem
+ fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory, true)
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
index 9425f8b99..87e579fa7 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
@@ -4,6 +4,30 @@
package org.yuzu.yuzu_emu.utils
object NativeConfig {
+ /**
+ * Creates a Config object and opens the emulation config.
+ */
+ @Synchronized
+ external fun initializeConfig()
+
+ /**
+ * Destroys the stored config object. This automatically saves the existing config.
+ */
+ @Synchronized
+ external fun unloadConfig()
+
+ /**
+ * Reads values saved to the config file and saves them.
+ */
+ @Synchronized
+ external fun reloadSettings()
+
+ /**
+ * Saves settings values in memory to disk.
+ */
+ @Synchronized
+ external fun saveSettings()
+
external fun getBoolean(key: String, getDefault: Boolean): Boolean
external fun setBoolean(key: String, value: Boolean)
diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt
index 1c36661f5..2acc93da8 100644
--- a/src/android/app/src/main/jni/CMakeLists.txt
+++ b/src/android/app/src/main/jni/CMakeLists.txt
@@ -6,9 +6,6 @@ add_library(yuzu-android SHARED
android_common/android_common.h
applets/software_keyboard.cpp
applets/software_keyboard.h
- config.cpp
- config.h
- default_ini.h
emu_window/emu_window.cpp
emu_window/emu_window.h
id_cache.cpp
@@ -16,14 +13,17 @@ add_library(yuzu-android SHARED
native.cpp
native.h
native_config.cpp
- uisettings.cpp
+ android_settings.cpp
game_metadata.cpp
+ native_log.cpp
+ android_config.cpp
+ android_config.h
)
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
-target_link_libraries(yuzu-android PRIVATE audio_core common core input_common)
-target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics log)
+target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common)
+target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log)
if (ARCHITECTURE_arm64)
target_link_libraries(yuzu-android PRIVATE adrenotools)
endif()
diff --git a/src/android/app/src/main/jni/android_config.cpp b/src/android/app/src/main/jni/android_config.cpp
new file mode 100644
index 000000000..3041c25c9
--- /dev/null
+++ b/src/android/app/src/main/jni/android_config.cpp
@@ -0,0 +1,70 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "android_config.h"
+#include "android_settings.h"
+#include "common/settings_setting.h"
+
+AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_type)
+ : Config(config_type) {
+ Initialize(config_name);
+ if (config_type != ConfigType::InputProfile) {
+ ReadAndroidValues();
+ SaveAndroidValues();
+ }
+}
+
+AndroidConfig::~AndroidConfig() {
+ if (global) {
+ AndroidConfig::SaveAllValues();
+ }
+}
+
+void AndroidConfig::ReloadAllValues() {
+ Reload();
+ ReadAndroidValues();
+ SaveAndroidValues();
+}
+
+void AndroidConfig::SaveAllValues() {
+ Save();
+ SaveAndroidValues();
+}
+
+void AndroidConfig::ReadAndroidValues() {
+ if (global) {
+ ReadAndroidUIValues();
+ }
+}
+
+void AndroidConfig::ReadAndroidUIValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Android));
+
+ ReadCategory(Settings::Category::Android);
+
+ EndGroup();
+}
+
+void AndroidConfig::SaveAndroidValues() {
+ if (global) {
+ SaveAndroidUIValues();
+ }
+
+ WriteToIni();
+}
+
+void AndroidConfig::SaveAndroidUIValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Android));
+
+ WriteCategory(Settings::Category::Android);
+
+ EndGroup();
+}
+
+std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) {
+ auto& map = Settings::values.linkage.by_category;
+ if (map.contains(category)) {
+ return Settings::values.linkage.by_category[category];
+ }
+ return AndroidSettings::values.linkage.by_category[category];
+}
diff --git a/src/android/app/src/main/jni/android_config.h b/src/android/app/src/main/jni/android_config.h
new file mode 100644
index 000000000..e679392fd
--- /dev/null
+++ b/src/android/app/src/main/jni/android_config.h
@@ -0,0 +1,41 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "frontend_common/config.h"
+
+class AndroidConfig final : public Config {
+public:
+ explicit AndroidConfig(const std::string& config_name = "config",
+ ConfigType config_type = ConfigType::GlobalConfig);
+ ~AndroidConfig() override;
+
+ void ReloadAllValues() override;
+ void SaveAllValues() override;
+
+protected:
+ void ReadAndroidValues();
+ void ReadAndroidUIValues();
+ void ReadHidbusValues() override {}
+ void ReadDebugControlValues() override {}
+ void ReadPathValues() override {}
+ void ReadShortcutValues() override {}
+ void ReadUIValues() override {}
+ void ReadUIGamelistValues() override {}
+ void ReadUILayoutValues() override {}
+ void ReadMultiplayerValues() override {}
+
+ void SaveAndroidValues();
+ void SaveAndroidUIValues();
+ void SaveHidbusValues() override {}
+ void SaveDebugControlValues() override {}
+ void SavePathValues() override {}
+ void SaveShortcutValues() override {}
+ void SaveUIValues() override {}
+ void SaveUIGamelistValues() override {}
+ void SaveUILayoutValues() override {}
+ void SaveMultiplayerValues() override {}
+
+ std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override;
+};
diff --git a/src/android/app/src/main/jni/uisettings.cpp b/src/android/app/src/main/jni/android_settings.cpp
index f2f0bad50..16023a6b0 100644
--- a/src/android/app/src/main/jni/uisettings.cpp
+++ b/src/android/app/src/main/jni/android_settings.cpp
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include "uisettings.h"
+#include "android_settings.h"
namespace AndroidSettings {
diff --git a/src/android/app/src/main/jni/uisettings.h b/src/android/app/src/main/jni/android_settings.h
index 494654af7..37bc33918 100644
--- a/src/android/app/src/main/jni/uisettings.h
+++ b/src/android/app/src/main/jni/android_settings.h
@@ -13,7 +13,7 @@ struct Values {
Settings::Linkage linkage;
// Android
- Settings::Setting<bool> picture_in_picture{linkage, true, "picture_in_picture",
+ Settings::Setting<bool> picture_in_picture{linkage, false, "picture_in_picture",
Settings::Category::Android};
Settings::Setting<s32> screen_layout{linkage,
5,
diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp
deleted file mode 100644
index 81120ab0f..000000000
--- a/src/android/app/src/main/jni/config.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <memory>
-#include <optional>
-#include <sstream>
-
-#include <INIReader.h>
-#include "common/fs/file.h"
-#include "common/fs/fs.h"
-#include "common/fs/path_util.h"
-#include "common/logging/log.h"
-#include "common/settings.h"
-#include "common/settings_enums.h"
-#include "core/hle/service/acc/profile_manager.h"
-#include "input_common/main.h"
-#include "jni/config.h"
-#include "jni/default_ini.h"
-#include "uisettings.h"
-
-namespace FS = Common::FS;
-
-Config::Config(const std::string& config_name, ConfigType config_type)
- : type(config_type), global{config_type == ConfigType::GlobalConfig} {
- Initialize(config_name);
-}
-
-Config::~Config() = default;
-
-bool Config::LoadINI(const std::string& default_contents, bool retry) {
- void(FS::CreateParentDir(config_loc));
- config = std::make_unique<INIReader>(FS::PathToUTF8String(config_loc));
- const auto config_loc_str = FS::PathToUTF8String(config_loc);
- if (config->ParseError() < 0) {
- if (retry) {
- LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...",
- config_loc_str);
-
- void(FS::CreateParentDir(config_loc));
- void(FS::WriteStringToFile(config_loc, FS::FileType::TextFile, default_contents));
-
- config = std::make_unique<INIReader>(config_loc_str);
-
- return LoadINI(default_contents, false);
- }
- LOG_ERROR(Config, "Failed.");
- return false;
- }
- LOG_INFO(Config, "Successfully loaded {}", config_loc_str);
- return true;
-}
-
-template <>
-void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) {
- std::string setting_value = config->Get(group, setting.GetLabel(), setting.GetDefault());
- if (setting_value.empty()) {
- setting_value = setting.GetDefault();
- }
- setting = std::move(setting_value);
-}
-
-template <>
-void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& setting) {
- setting = config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
-}
-
-template <typename Type, bool ranged>
-void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) {
- setting = static_cast<Type>(
- config->GetInteger(group, setting.GetLabel(), static_cast<long>(setting.GetDefault())));
-}
-
-void Config::ReadValues() {
- ReadSetting("ControlsGeneral", Settings::values.mouse_enabled);
- ReadSetting("ControlsGeneral", Settings::values.touch_device);
- ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled);
- ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled);
- ReadSetting("ControlsGeneral", Settings::values.vibration_enabled);
- ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations);
- ReadSetting("ControlsGeneral", Settings::values.motion_enabled);
- Settings::values.touchscreen.enabled =
- config->GetBoolean("ControlsGeneral", "touch_enabled", true);
- Settings::values.touchscreen.rotation_angle =
- config->GetInteger("ControlsGeneral", "touch_angle", 0);
- Settings::values.touchscreen.diameter_x =
- config->GetInteger("ControlsGeneral", "touch_diameter_x", 15);
- Settings::values.touchscreen.diameter_y =
- config->GetInteger("ControlsGeneral", "touch_diameter_y", 15);
-
- int num_touch_from_button_maps =
- config->GetInteger("ControlsGeneral", "touch_from_button_map", 0);
- if (num_touch_from_button_maps > 0) {
- for (int i = 0; i < num_touch_from_button_maps; ++i) {
- Settings::TouchFromButtonMap map;
- map.name = config->Get("ControlsGeneral",
- std::string("touch_from_button_maps_") + std::to_string(i) +
- std::string("_name"),
- "default");
- const int num_touch_maps = config->GetInteger(
- "ControlsGeneral",
- std::string("touch_from_button_maps_") + std::to_string(i) + std::string("_count"),
- 0);
- map.buttons.reserve(num_touch_maps);
-
- for (int j = 0; j < num_touch_maps; ++j) {
- std::string touch_mapping =
- config->Get("ControlsGeneral",
- std::string("touch_from_button_maps_") + std::to_string(i) +
- std::string("_bind_") + std::to_string(j),
- "");
- map.buttons.emplace_back(std::move(touch_mapping));
- }
-
- Settings::values.touch_from_button_maps.emplace_back(std::move(map));
- }
- } else {
- Settings::values.touch_from_button_maps.emplace_back(
- Settings::TouchFromButtonMap{"default", {}});
- num_touch_from_button_maps = 1;
- }
- Settings::values.touch_from_button_map_index = std::clamp(
- Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
-
- ReadSetting("ControlsGeneral", Settings::values.udp_input_servers);
-
- // Data Storage
- ReadSetting("Data Storage", Settings::values.use_virtual_sd);
- FS::SetYuzuPath(FS::YuzuPath::NANDDir,
- config->Get("Data Storage", "nand_directory",
- FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
- FS::SetYuzuPath(FS::YuzuPath::SDMCDir,
- config->Get("Data Storage", "sdmc_directory",
- FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
- FS::SetYuzuPath(FS::YuzuPath::LoadDir,
- config->Get("Data Storage", "load_directory",
- FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
- FS::SetYuzuPath(FS::YuzuPath::DumpDir,
- config->Get("Data Storage", "dump_directory",
- FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
- ReadSetting("Data Storage", Settings::values.gamecard_inserted);
- ReadSetting("Data Storage", Settings::values.gamecard_current_game);
- ReadSetting("Data Storage", Settings::values.gamecard_path);
-
- // System
- ReadSetting("System", Settings::values.current_user);
- Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 0,
- Service::Account::MAX_USERS - 1);
-
- // Disable docked mode by default on Android
- Settings::values.use_docked_mode.SetValue(config->GetBoolean("System", "use_docked_mode", false)
- ? Settings::ConsoleMode::Docked
- : Settings::ConsoleMode::Handheld);
-
- const auto rng_seed_enabled = config->GetBoolean("System", "rng_seed_enabled", false);
- if (rng_seed_enabled) {
- Settings::values.rng_seed.SetValue(config->GetInteger("System", "rng_seed", 0));
- } else {
- Settings::values.rng_seed.SetValue(0);
- }
- Settings::values.rng_seed_enabled.SetValue(rng_seed_enabled);
-
- const auto custom_rtc_enabled = config->GetBoolean("System", "custom_rtc_enabled", false);
- if (custom_rtc_enabled) {
- Settings::values.custom_rtc = config->GetInteger("System", "custom_rtc", 0);
- } else {
- Settings::values.custom_rtc = 0;
- }
- Settings::values.custom_rtc_enabled = custom_rtc_enabled;
-
- ReadSetting("System", Settings::values.language_index);
- ReadSetting("System", Settings::values.region_index);
- ReadSetting("System", Settings::values.time_zone_index);
- ReadSetting("System", Settings::values.sound_index);
-
- // Core
- ReadSetting("Core", Settings::values.use_multi_core);
- ReadSetting("Core", Settings::values.memory_layout_mode);
-
- // Cpu
- ReadSetting("Cpu", Settings::values.cpu_accuracy);
- ReadSetting("Cpu", Settings::values.cpu_debug_mode);
- ReadSetting("Cpu", Settings::values.cpuopt_page_tables);
- ReadSetting("Cpu", Settings::values.cpuopt_block_linking);
- ReadSetting("Cpu", Settings::values.cpuopt_return_stack_buffer);
- ReadSetting("Cpu", Settings::values.cpuopt_fast_dispatcher);
- ReadSetting("Cpu", Settings::values.cpuopt_context_elimination);
- ReadSetting("Cpu", Settings::values.cpuopt_const_prop);
- ReadSetting("Cpu", Settings::values.cpuopt_misc_ir);
- ReadSetting("Cpu", Settings::values.cpuopt_reduce_misalign_checks);
- ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
- ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives);
- ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives);
- ReadSetting("Cpu", Settings::values.cpuopt_ignore_memory_aborts);
- ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
- ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
- ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
- ReadSetting("Cpu", Settings::values.cpuopt_unsafe_inaccurate_nan);
- ReadSetting("Cpu", Settings::values.cpuopt_unsafe_fastmem_check);
- ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_global_monitor);
-
- // Renderer
- ReadSetting("Renderer", Settings::values.renderer_backend);
- ReadSetting("Renderer", Settings::values.renderer_debug);
- ReadSetting("Renderer", Settings::values.renderer_shader_feedback);
- ReadSetting("Renderer", Settings::values.enable_nsight_aftermath);
- ReadSetting("Renderer", Settings::values.disable_shader_loop_safety_checks);
- ReadSetting("Renderer", Settings::values.vulkan_device);
-
- ReadSetting("Renderer", Settings::values.resolution_setup);
- ReadSetting("Renderer", Settings::values.scaling_filter);
- ReadSetting("Renderer", Settings::values.fsr_sharpening_slider);
- ReadSetting("Renderer", Settings::values.anti_aliasing);
- ReadSetting("Renderer", Settings::values.fullscreen_mode);
- ReadSetting("Renderer", Settings::values.aspect_ratio);
- ReadSetting("Renderer", Settings::values.max_anisotropy);
- ReadSetting("Renderer", Settings::values.use_speed_limit);
- ReadSetting("Renderer", Settings::values.speed_limit);
- ReadSetting("Renderer", Settings::values.use_disk_shader_cache);
- ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation);
- ReadSetting("Renderer", Settings::values.vsync_mode);
- ReadSetting("Renderer", Settings::values.shader_backend);
- ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);
- ReadSetting("Renderer", Settings::values.nvdec_emulation);
- ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
- ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache);
-
- ReadSetting("Renderer", Settings::values.bg_red);
- ReadSetting("Renderer", Settings::values.bg_green);
- ReadSetting("Renderer", Settings::values.bg_blue);
-
- // Use GPU accuracy normal by default on Android
- Settings::values.gpu_accuracy = static_cast<Settings::GpuAccuracy>(config->GetInteger(
- "Renderer", "gpu_accuracy", static_cast<u32>(Settings::GpuAccuracy::Normal)));
-
- // Use GPU default anisotropic filtering on Android
- Settings::values.max_anisotropy =
- static_cast<Settings::AnisotropyMode>(config->GetInteger("Renderer", "max_anisotropy", 1));
-
- // Disable ASTC compute by default on Android
- Settings::values.accelerate_astc.SetValue(
- config->GetBoolean("Renderer", "accelerate_astc", false) ? Settings::AstcDecodeMode::Gpu
- : Settings::AstcDecodeMode::Cpu);
-
- // Enable asynchronous presentation by default on Android
- Settings::values.async_presentation =
- config->GetBoolean("Renderer", "async_presentation", true);
-
- // Disable force_max_clock by default on Android
- Settings::values.renderer_force_max_clock =
- config->GetBoolean("Renderer", "force_max_clock", false);
-
- // Disable use_reactive_flushing by default on Android
- Settings::values.use_reactive_flushing =
- config->GetBoolean("Renderer", "use_reactive_flushing", false);
-
- // Audio
- ReadSetting("Audio", Settings::values.sink_id);
- ReadSetting("Audio", Settings::values.audio_output_device_id);
- ReadSetting("Audio", Settings::values.volume);
-
- // Miscellaneous
- // log_filter has a different default here than from common
- Settings::values.log_filter = "*:Info";
- ReadSetting("Miscellaneous", Settings::values.use_dev_keys);
-
- // Debugging
- Settings::values.record_frame_times =
- config->GetBoolean("Debugging", "record_frame_times", false);
- ReadSetting("Debugging", Settings::values.dump_exefs);
- ReadSetting("Debugging", Settings::values.dump_nso);
- ReadSetting("Debugging", Settings::values.enable_fs_access_log);
- ReadSetting("Debugging", Settings::values.reporting_services);
- ReadSetting("Debugging", Settings::values.quest_flag);
- ReadSetting("Debugging", Settings::values.use_debug_asserts);
- ReadSetting("Debugging", Settings::values.use_auto_stub);
- ReadSetting("Debugging", Settings::values.disable_macro_jit);
- ReadSetting("Debugging", Settings::values.disable_macro_hle);
- ReadSetting("Debugging", Settings::values.use_gdbstub);
- ReadSetting("Debugging", Settings::values.gdbstub_port);
-
- const auto title_list = config->Get("AddOns", "title_ids", "");
- std::stringstream ss(title_list);
- std::string line;
- while (std::getline(ss, line, '|')) {
- const auto title_id = std::strtoul(line.c_str(), nullptr, 16);
- const auto disabled_list = config->Get("AddOns", "disabled_" + line, "");
-
- std::stringstream inner_ss(disabled_list);
- std::string inner_line;
- std::vector<std::string> out;
- while (std::getline(inner_ss, inner_line, '|')) {
- out.push_back(inner_line);
- }
-
- Settings::values.disabled_addons.insert_or_assign(title_id, out);
- }
-
- // Web Service
- ReadSetting("WebService", Settings::values.enable_telemetry);
- ReadSetting("WebService", Settings::values.web_api_url);
- ReadSetting("WebService", Settings::values.yuzu_username);
- ReadSetting("WebService", Settings::values.yuzu_token);
-
- // Network
- ReadSetting("Network", Settings::values.network_interface);
-
- // Android
- ReadSetting("Android", AndroidSettings::values.picture_in_picture);
- ReadSetting("Android", AndroidSettings::values.screen_layout);
-}
-
-void Config::Initialize(const std::string& config_name) {
- const auto fs_config_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir);
- const auto config_file = fmt::format("{}.ini", config_name);
-
- switch (type) {
- case ConfigType::GlobalConfig:
- config_loc = FS::PathToUTF8String(fs_config_loc / config_file);
- break;
- case ConfigType::PerGameConfig:
- config_loc = FS::PathToUTF8String(fs_config_loc / "custom" / FS::ToU8String(config_file));
- break;
- case ConfigType::InputProfile:
- config_loc = FS::PathToUTF8String(fs_config_loc / "input" / config_file);
- LoadINI(DefaultINI::android_config_file);
- return;
- }
- LoadINI(DefaultINI::android_config_file);
- ReadValues();
-}
diff --git a/src/android/app/src/main/jni/config.h b/src/android/app/src/main/jni/config.h
deleted file mode 100644
index e1e8f47ed..000000000
--- a/src/android/app/src/main/jni/config.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <filesystem>
-#include <memory>
-#include <optional>
-#include <string>
-
-#include "common/settings.h"
-
-class INIReader;
-
-class Config {
- bool LoadINI(const std::string& default_contents = "", bool retry = true);
-
-public:
- enum class ConfigType {
- GlobalConfig,
- PerGameConfig,
- InputProfile,
- };
-
- explicit Config(const std::string& config_name = "config",
- ConfigType config_type = ConfigType::GlobalConfig);
- ~Config();
-
- void Initialize(const std::string& config_name);
-
-private:
- /**
- * Applies a value read from the config to a Setting.
- *
- * @param group The name of the INI group
- * @param setting The yuzu setting to modify
- */
- template <typename Type, bool ranged>
- void ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting);
-
- void ReadValues();
-
- const ConfigType type;
- std::unique_ptr<INIReader> config;
- std::string config_loc;
- const bool global;
-};
diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h
deleted file mode 100644
index d81422a74..000000000
--- a/src/android/app/src/main/jni/default_ini.h
+++ /dev/null
@@ -1,511 +0,0 @@
-// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-namespace DefaultINI {
-
-const char* android_config_file = R"(
-
-[ControlsP0]
-# The input devices and parameters for each Switch native input
-# The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ...
-# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..."
-# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values
-
-# Indicates if this player should be connected at boot
-connected=
-
-# for button input, the following devices are available:
-# - "keyboard" (default) for keyboard input. Required parameters:
-# - "code": the code of the key to bind
-# - "sdl" for joystick input using SDL. Required parameters:
-# - "guid": SDL identification GUID of the joystick
-# - "port": the index of the joystick to bind
-# - "button"(optional): the index of the button to bind
-# - "hat"(optional): the index of the hat to bind as direction buttons
-# - "axis"(optional): the index of the axis to bind
-# - "direction"(only used for hat): the direction name of the hat to bind. Can be "up", "down", "left" or "right"
-# - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is
-# triggered if the axis value crosses
-# - "direction"(only used for axis): "+" means the button is triggered when the axis value
-# is greater than the threshold; "-" means the button is triggered when the axis value
-# is smaller than the threshold
-button_a=
-button_b=
-button_x=
-button_y=
-button_lstick=
-button_rstick=
-button_l=
-button_r=
-button_zl=
-button_zr=
-button_plus=
-button_minus=
-button_dleft=
-button_dup=
-button_dright=
-button_ddown=
-button_lstick_left=
-button_lstick_up=
-button_lstick_right=
-button_lstick_down=
-button_sl=
-button_sr=
-button_home=
-button_screenshot=
-
-# for analog input, the following devices are available:
-# - "analog_from_button" (default) for emulating analog input from direction buttons. Required parameters:
-# - "up", "down", "left", "right": sub-devices for each direction.
-# Should be in the format as a button input devices using escape characters, for example, "engine$0keyboard$1code$00"
-# - "modifier": sub-devices as a modifier.
-# - "modifier_scale": a float number representing the applied modifier scale to the analog input.
-# Must be in range of 0.0-1.0. Defaults to 0.5
-# - "sdl" for joystick input using SDL. Required parameters:
-# - "guid": SDL identification GUID of the joystick
-# - "port": the index of the joystick to bind
-# - "axis_x": the index of the axis to bind as x-axis (default to 0)
-# - "axis_y": the index of the axis to bind as y-axis (default to 1)
-lstick=
-rstick=
-
-# for motion input, the following devices are available:
-# - "keyboard" (default) for emulating random motion input from buttons. Required parameters:
-# - "code": the code of the key to bind
-# - "sdl" for motion input using SDL. Required parameters:
-# - "guid": SDL identification GUID of the joystick
-# - "port": the index of the joystick to bind
-# - "motion": the index of the motion sensor to bind
-# - "cemuhookudp" for motion input using Cemu Hook protocol. Required parameters:
-# - "guid": the IP address of the cemu hook server encoded to a hex string. for example 192.168.0.1 = "c0a80001"
-# - "port": the port of the cemu hook server
-# - "pad": the index of the joystick
-# - "motion": the index of the motion sensor of the joystick to bind
-motionleft=
-motionright=
-
-[ControlsGeneral]
-# To use the debug_pad, prepend `debug_pad_` before each button setting above.
-# i.e. debug_pad_button_a=
-
-# Enable debug pad inputs to the guest
-# 0 (default): Disabled, 1: Enabled
-debug_pad_enabled =
-
-# Whether to enable or disable vibration
-# 0: Disabled, 1 (default): Enabled
-vibration_enabled=
-
-# Whether to enable or disable accurate vibrations
-# 0 (default): Disabled, 1: Enabled
-enable_accurate_vibrations=
-
-# Enables controller motion inputs
-# 0: Disabled, 1 (default): Enabled
-motion_enabled =
-
-# Defines the udp device's touch screen coordinate system for cemuhookudp devices
-# - "min_x", "min_y", "max_x", "max_y"
-touch_device=
-
-# for mapping buttons to touch inputs.
-#touch_from_button_map=1
-#touch_from_button_maps_0_name=default
-#touch_from_button_maps_0_count=2
-#touch_from_button_maps_0_bind_0=foo
-#touch_from_button_maps_0_bind_1=bar
-# etc.
-
-# List of Cemuhook UDP servers, delimited by ','.
-# Default: 127.0.0.1:26760
-# Example: 127.0.0.1:26760,123.4.5.67:26761
-udp_input_servers =
-
-# Enable controlling an axis via a mouse input.
-# 0 (default): Off, 1: On
-mouse_panning =
-
-# Set mouse sensitivity.
-# Default: 1.0
-mouse_panning_sensitivity =
-
-# Emulate an analog control stick from keyboard inputs.
-# 0 (default): Disabled, 1: Enabled
-emulate_analog_keyboard =
-
-# Enable mouse inputs to the guest
-# 0 (default): Disabled, 1: Enabled
-mouse_enabled =
-
-# Enable keyboard inputs to the guest
-# 0 (default): Disabled, 1: Enabled
-keyboard_enabled =
-
-[Core]
-# Whether to use multi-core for CPU emulation
-# 0: Disabled, 1 (default): Enabled
-use_multi_core =
-
-# Enable unsafe extended guest system memory layout (8GB DRAM)
-# 0 (default): Disabled, 1: Enabled
-use_unsafe_extended_memory_layout =
-
-[Cpu]
-# Adjusts various optimizations.
-# Auto-select mode enables choice unsafe optimizations.
-# Accurate enables only safe optimizations.
-# Unsafe allows any unsafe optimizations.
-# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations
-cpu_accuracy =
-
-# Allow disabling safe optimizations.
-# 0 (default): Disabled, 1: Enabled
-cpu_debug_mode =
-
-# Enable inline page tables optimization (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_page_tables =
-
-# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_block_linking =
-
-# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_return_stack_buffer =
-
-# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_fast_dispatcher =
-
-# Enable context elimination CPU Optimization (reduce host memory use for guest context)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_context_elimination =
-
-# Enable constant propagation CPU optimization (basic IR optimization)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_const_prop =
-
-# Enable miscellaneous CPU optimizations (basic IR optimization)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_misc_ir =
-
-# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_reduce_misalign_checks =
-
-# Enable Host MMU Emulation (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_fastmem =
-
-# Enable Host MMU Emulation for exclusive memory instructions (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_fastmem_exclusives =
-
-# Enable fallback on failure of fastmem of exclusive memory instructions (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_recompile_exclusives =
-
-# Enable optimization to ignore invalid memory accesses (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_ignore_memory_aborts =
-
-# Enable unfuse FMA (improve performance on CPUs without FMA)
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_unfuse_fma =
-
-# Enable faster FRSQRTE and FRECPE
-# Only enabled if cpu_accuracy is set to Unsafe.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_reduce_fp_error =
-
-# Enable faster ASIMD instructions (32 bits only)
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_ignore_standard_fpcr =
-
-# Enable inaccurate NaN handling
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_inaccurate_nan =
-
-# Disable address space checks (64 bits only)
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_fastmem_check =
-
-# Enable faster exclusive instructions
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_ignore_global_monitor =
-
-[Renderer]
-# Which backend API to use.
-# 0: OpenGL (unsupported), 1 (default): Vulkan, 2: Null
-backend =
-
-# Whether to enable asynchronous presentation (Vulkan only)
-# 0: Off, 1 (default): On
-async_presentation =
-
-# Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied).
-# 0 (default): Disabled, 1: Enabled
-force_max_clock =
-
-# Enable graphics API debugging mode.
-# 0 (default): Disabled, 1: Enabled
-debug =
-
-# Enable shader feedback.
-# 0 (default): Disabled, 1: Enabled
-renderer_shader_feedback =
-
-# Enable Nsight Aftermath crash dumps
-# 0 (default): Disabled, 1: Enabled
-nsight_aftermath =
-
-# Disable shader loop safety checks, executing the shader without loop logic changes
-# 0 (default): Disabled, 1: Enabled
-disable_shader_loop_safety_checks =
-
-# Which Vulkan physical device to use (defaults to 0)
-vulkan_device =
-
-# 0: 0.5x (360p/540p) [EXPERIMENTAL]
-# 1: 0.75x (540p/810p) [EXPERIMENTAL]
-# 2 (default): 1x (720p/1080p)
-# 3: 2x (1440p/2160p)
-# 4: 3x (2160p/3240p)
-# 5: 4x (2880p/4320p)
-# 6: 5x (3600p/5400p)
-# 7: 6x (4320p/6480p)
-resolution_setup =
-
-# Pixel filter to use when up- or down-sampling rendered frames.
-# 0: Nearest Neighbor
-# 1 (default): Bilinear
-# 2: Bicubic
-# 3: Gaussian
-# 4: ScaleForce
-# 5: AMD FidelityFX™️ Super Resolution [Vulkan Only]
-scaling_filter =
-
-# Anti-Aliasing (AA)
-# 0 (default): None, 1: FXAA
-anti_aliasing =
-
-# Whether to use fullscreen or borderless window mode
-# 0 (Windows default): Borderless window, 1 (All other default): Exclusive fullscreen
-fullscreen_mode =
-
-# Aspect ratio
-# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Force 16:10, 4: Stretch to Window
-aspect_ratio =
-
-# Anisotropic filtering
-# 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x
-max_anisotropy =
-
-# Whether to enable VSync or not.
-# OpenGL: Values other than 0 enable VSync
-# Vulkan: FIFO is selected if the requested mode is not supported by the driver.
-# FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate.
-# FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down.
-# Mailbox can have lower latency than FIFO and does not tear but may drop frames.
-# Immediate (no synchronization) just presents whatever is available and can exhibit tearing.
-# 0: Immediate (Off), 1 (Default): Mailbox (On), 2: FIFO, 3: FIFO Relaxed
-use_vsync =
-
-# Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is
-# not available and GLASM is selected, GLSL will be used.
-# 0: GLSL, 1 (default): GLASM, 2: SPIR-V
-shader_backend =
-
-# Whether to allow asynchronous shader building.
-# 0 (default): Off, 1: On
-use_asynchronous_shaders =
-
-# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory.
-# 0 (default): Off, 1: On
-use_reactive_flushing =
-
-# NVDEC emulation.
-# 0: Disabled, 1: CPU Decoding, 2 (default): GPU Decoding
-nvdec_emulation =
-
-# Accelerate ASTC texture decoding.
-# 0 (default): Off, 1: On
-accelerate_astc =
-
-# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value
-# 0: Off, 1: On (default)
-use_speed_limit =
-
-# Limits the speed of the game to run no faster than this value as a percentage of target speed
-# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default)
-speed_limit =
-
-# Whether to use disk based shader cache
-# 0: Off, 1 (default): On
-use_disk_shader_cache =
-
-# Which gpu accuracy level to use
-# 0 (default): Normal, 1: High, 2: Extreme (Very slow)
-gpu_accuracy =
-
-# Whether to use asynchronous GPU emulation
-# 0 : Off (slow), 1 (default): On (fast)
-use_asynchronous_gpu_emulation =
-
-# Inform the guest that GPU operations completed more quickly than they did.
-# 0: Off, 1 (default): On
-use_fast_gpu_time =
-
-# Force unmodified buffers to be flushed, which can cost performance.
-# 0: Off (default), 1: On
-use_pessimistic_flushes =
-
-# Whether to use garbage collection or not for GPU caches.
-# 0 (default): Off, 1: On
-use_caches_gc =
-
-# The clear color for the renderer. What shows up on the sides of the bottom screen.
-# Must be in range of 0-255. Defaults to 0 for all.
-bg_red =
-bg_blue =
-bg_green =
-
-[Audio]
-# Which audio output engine to use.
-# auto (default): Auto-select
-# cubeb: Cubeb audio engine (if available)
-# sdl2: SDL2 audio engine (if available)
-# null: No audio output
-output_engine =
-
-# Which audio device to use.
-# auto (default): Auto-select
-output_device =
-
-# Output volume.
-# 100 (default): 100%, 0; mute
-volume =
-
-[Data Storage]
-# Whether to create a virtual SD card.
-# 1: Yes, 0 (default): No
-use_virtual_sd =
-
-# Whether or not to enable gamecard emulation
-# 1: Yes, 0 (default): No
-gamecard_inserted =
-
-# Whether or not the gamecard should be emulated as the current game
-# If 'gamecard_inserted' is 0 this setting is irrelevant
-# 1: Yes, 0 (default): No
-gamecard_current_game =
-
-# Path to an XCI file to use as the gamecard
-# If 'gamecard_inserted' is 0 this setting is irrelevant
-# If 'gamecard_current_game' is 1 this setting is irrelevant
-gamecard_path =
-
-[System]
-# Whether the system is docked
-# 1 (default): Yes, 0: No
-use_docked_mode =
-
-# Sets the seed for the RNG generator built into the switch
-# rng_seed will be ignored and randomly generated if rng_seed_enabled is false
-rng_seed_enabled =
-rng_seed =
-
-# Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service
-# This will auto-increment, with the time set being the time the game is started
-# This override will only occur if custom_rtc_enabled is true, otherwise the current time is used
-custom_rtc_enabled =
-custom_rtc =
-
-# Sets the systems language index
-# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
-# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
-# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Brazilian Portuguese
-language_index =
-
-# The system region that yuzu will use during emulation
-# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
-region_index =
-
-# The system time zone that yuzu will use during emulation
-# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone
-time_zone_index =
-
-# Sets the sound output mode.
-# 0: Mono, 1 (default): Stereo, 2: Surround
-sound_index =
-
-[Miscellaneous]
-# A filter which removes logs below a certain logging level.
-# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical
-log_filter = *:Trace
-
-# Use developer keys
-# 0 (default): Disabled, 1: Enabled
-use_dev_keys =
-
-[Debugging]
-# Record frame time data, can be found in the log directory. Boolean value
-record_frame_times =
-# Determines whether or not yuzu will dump the ExeFS of all games it attempts to load while loading them
-dump_exefs=false
-# Determines whether or not yuzu will dump all NSOs it attempts to load while loading them
-dump_nso=false
-# Determines whether or not yuzu will save the filesystem access log.
-enable_fs_access_log=false
-# Enables verbose reporting services
-reporting_services =
-# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
-# false: Retail/Normal Mode (default), true: Kiosk Mode
-quest_flag =
-# Determines whether debug asserts should be enabled, which will throw an exception on asserts.
-# false: Disabled (default), true: Enabled
-use_debug_asserts =
-# Determines whether unimplemented HLE service calls should be automatically stubbed.
-# false: Disabled (default), true: Enabled
-use_auto_stub =
-# Enables/Disables the macro JIT compiler
-disable_macro_jit=false
-# Determines whether to enable the GDB stub and wait for the debugger to attach before running.
-# false: Disabled (default), true: Enabled
-use_gdbstub=false
-# The port to use for the GDB server, if it is enabled.
-gdbstub_port=6543
-
-[WebService]
-# Whether or not to enable telemetry
-# 0: No, 1 (default): Yes
-enable_telemetry =
-# URL for Web API
-web_api_url = https://api.yuzu-emu.org
-# Username and token for yuzu Web Service
-# See https://profile.yuzu-emu.org/ for more info
-yuzu_username =
-yuzu_token =
-
-[Network]
-# Name of the network interface device to use with yuzu LAN play.
-# e.g. On *nix: 'enp7s0', 'wlp6s0u1u3u3', 'lo'
-# e.g. On Windows: 'Ethernet', 'Wi-Fi'
-network_interface =
-
-[AddOns]
-# Used to disable add-ons
-# List of title IDs of games that will have add-ons disabled (separated by '|'):
-title_ids =
-# For each title ID, have a key/value pair called `disabled_<title_id>` equal to the names of the add-ons to disable (sep. by '|')
-# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey
-)";
-} // namespace DefaultINI
diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp
index a7e414b81..c4f631924 100644
--- a/src/android/app/src/main/jni/emu_window/emu_window.cpp
+++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp
@@ -9,6 +9,7 @@
#include "input_common/drivers/virtual_gamepad.h"
#include "input_common/main.h"
#include "jni/emu_window/emu_window.h"
+#include "jni/native.h"
void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
m_window_width = ANativeWindow_getWidth(surface);
@@ -57,6 +58,13 @@ void EmuWindow_Android::OnRemoveNfcTag() {
m_input_subsystem->GetVirtualAmiibo()->CloseAmiibo();
}
+void EmuWindow_Android::OnFrameDisplayed() {
+ if (!m_first_frame) {
+ EmulationSession::GetInstance().OnEmulationStarted();
+ m_first_frame = true;
+ }
+}
+
EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem,
ANativeWindow* surface,
std::shared_ptr<Common::DynamicLibrary> driver_library)
diff --git a/src/android/app/src/main/jni/emu_window/emu_window.h b/src/android/app/src/main/jni/emu_window/emu_window.h
index b38087f73..a34a0e479 100644
--- a/src/android/app/src/main/jni/emu_window/emu_window.h
+++ b/src/android/app/src/main/jni/emu_window/emu_window.h
@@ -45,7 +45,7 @@ public:
float gyro_z, float accel_x, float accel_y, float accel_z);
void OnReadNfcTag(std::span<u8> data);
void OnRemoveNfcTag();
- void OnFrameDisplayed() override {}
+ void OnFrameDisplayed() override;
std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override {
return {std::make_unique<GraphicsContext_Android>(m_driver_library)};
@@ -61,4 +61,6 @@ private:
float m_window_height{};
std::shared_ptr<Common::DynamicLibrary> m_driver_library;
+
+ bool m_first_frame = false;
};
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 0e458df38..617288ae4 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -52,8 +52,8 @@
#include "core/hle/service/am/applets/applets.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/loader.h"
+#include "frontend_common/config.h"
#include "jni/android_common/android_common.h"
-#include "jni/config.h"
#include "jni/id_cache.h"
#include "jni/native.h"
#include "video_core/renderer_base.h"
@@ -199,8 +199,8 @@ bool EmulationSession::IsPaused() const {
return m_is_running && m_is_paused;
}
-const Core::PerfStatsResults& EmulationSession::PerfStats() const {
- std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
+const Core::PerfStatsResults& EmulationSession::PerfStats() {
+ m_perf_stats = m_system.GetAndResetPerfStats();
return m_perf_stats;
}
@@ -247,7 +247,14 @@ void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath)
}
}
-void EmulationSession::InitializeSystem() {
+void EmulationSession::InitializeSystem(bool reload) {
+ if (!reload) {
+ // Initialize logging system
+ Common::Log::Initialize();
+ Common::Log::SetColorConsoleBackendEnabled(true);
+ Common::Log::Start();
+ }
+
// Initialize filesystem.
m_system.SetFilesystem(m_vfs);
m_system.GetUserChannel().clear();
@@ -365,8 +372,6 @@ void EmulationSession::RunEmulation() {
m_system.InitializeDebugger();
}
- OnEmulationStarted();
-
while (true) {
{
[[maybe_unused]] std::unique_lock lock(m_mutex);
@@ -376,11 +381,6 @@ void EmulationSession::RunEmulation() {
break;
}
}
- {
- // Refresh performance stats.
- std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
- m_perf_stats = m_system.GetAndResetPerfStats();
- }
}
}
@@ -462,10 +462,6 @@ void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
}
static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
- Common::Log::Initialize();
- Common::Log::SetColorConsoleBackendEnabled(true);
- Common::Log::Start();
-
MicroProfileOnThreadCreate("EmuThread");
SCOPE_EXIT({ MicroProfileShutdown(); });
@@ -666,12 +662,13 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchReleased(JNIEnv* env, jclass c
}
}
-void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz) {
- // Create the default config.ini.
- Config{};
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz,
+ jboolean reload) {
// Initialize the emulated system.
- EmulationSession::GetInstance().System().Initialize();
- EmulationSession::GetInstance().InitializeSystem();
+ if (!reload) {
+ EmulationSession::GetInstance().System().Initialize();
+ }
+ EmulationSession::GetInstance().InitializeSystem(reload);
}
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) {
@@ -681,17 +678,6 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass cl
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z(
JNIEnv* env, jclass clazz, jstring j_file, jstring j_savestate, jboolean j_delete_savestate) {}
-void Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadSettings(JNIEnv* env, jclass clazz) {
- Config{};
-}
-
-void Java_org_yuzu_yuzu_1emu_NativeLibrary_initGameIni(JNIEnv* env, jclass clazz,
- jstring j_game_id) {
- std::string_view game_id = env->GetStringUTFChars(j_game_id, 0);
-
- env->ReleaseStringUTFChars(j_game_id, game_id.data());
-}
-
jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jclass clazz) {
jdoubleArray j_stats = env->NewDoubleArray(4);
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h
index 0aa2b085b..78ef96802 100644
--- a/src/android/app/src/main/jni/native.h
+++ b/src/android/app/src/main/jni/native.h
@@ -41,9 +41,9 @@ public:
void RunEmulation();
void ShutdownEmulation();
- const Core::PerfStatsResults& PerfStats() const;
+ const Core::PerfStatsResults& PerfStats();
void ConfigureFilesystemProvider(const std::string& filepath);
- void InitializeSystem();
+ void InitializeSystem(bool reload);
Core::SystemResultStatus InitializeEmulation(const std::string& filepath);
bool IsHandheldOnly();
@@ -52,9 +52,10 @@ public:
void OnGamepadDisconnectEvent([[maybe_unused]] int index);
SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard();
+ static void OnEmulationStarted();
+
private:
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max);
- static void OnEmulationStarted();
static void OnEmulationStopped(Core::SystemResultStatus result);
private:
@@ -80,6 +81,5 @@ private:
// Synchronization
std::condition_variable_any m_cv;
- mutable std::mutex m_perf_stats_mutex;
mutable std::mutex m_mutex;
};
diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp
index 8a704960c..8e81816e5 100644
--- a/src/android/app/src/main/jni/native_config.cpp
+++ b/src/android/app/src/main/jni/native_config.cpp
@@ -5,11 +5,14 @@
#include <jni.h>
+#include "android_config.h"
+#include "android_settings.h"
#include "common/logging/log.h"
#include "common/settings.h"
+#include "frontend_common/config.h"
#include "jni/android_common/android_common.h"
-#include "jni/config.h"
-#include "uisettings.h"
+
+std::unique_ptr<AndroidConfig> config;
template <typename T>
Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
@@ -28,6 +31,22 @@ Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
extern "C" {
+void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_initializeConfig(JNIEnv* env, jobject obj) {
+ config = std::make_unique<AndroidConfig>();
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_unloadConfig(JNIEnv* env, jobject obj) {
+ config.reset();
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_reloadSettings(JNIEnv* env, jobject obj) {
+ config->AndroidConfig::ReloadAllValues();
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_saveSettings(JNIEnv* env, jobject obj) {
+ config->AndroidConfig::SaveAllValues();
+}
+
jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getBoolean(JNIEnv* env, jobject obj,
jstring jkey, jboolean getDefault) {
auto setting = getSetting<bool>(env, jkey);
diff --git a/src/android/app/src/main/jni/native_log.cpp b/src/android/app/src/main/jni/native_log.cpp
new file mode 100644
index 000000000..33d691dc8
--- /dev/null
+++ b/src/android/app/src/main/jni/native_log.cpp
@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <common/logging/log.h>
+#include <jni.h>
+
+#include "android_common/android_common.h"
+
+extern "C" {
+
+void Java_org_yuzu_yuzu_1emu_utils_Log_debug(JNIEnv* env, jobject obj, jstring jmessage) {
+ LOG_DEBUG(Frontend, "{}", GetJString(env, jmessage));
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_Log_warning(JNIEnv* env, jobject obj, jstring jmessage) {
+ LOG_WARNING(Frontend, "{}", GetJString(env, jmessage));
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_Log_info(JNIEnv* env, jobject obj, jstring jmessage) {
+ LOG_INFO(Frontend, "{}", GetJString(env, jmessage));
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_Log_error(JNIEnv* env, jobject obj, jstring jmessage) {
+ LOG_ERROR(Frontend, "{}", GetJString(env, jmessage));
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_Log_critical(JNIEnv* env, jobject obj, jstring jmessage) {
+ LOG_CRITICAL(Frontend, "{}", GetJString(env, jmessage));
+}
+
+} // extern "C"
diff --git a/src/android/app/src/main/res/drawable/ic_audio.xml b/src/android/app/src/main/res/drawable/ic_audio.xml
new file mode 100644
index 000000000..e306c3b0c
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_audio.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="?attr/colorControlNormal"
+ android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z" />
+</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_code.xml b/src/android/app/src/main/res/drawable/ic_code.xml
new file mode 100644
index 000000000..26f83b39b
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_code.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960">
+ <path
+ android:fillColor="?attr/colorControlNormal"
+ android:pathData="M320,720 L80,480l240,-240 57,57 -184,184 183,183 -56,56ZM640,720 L583,663 767,479 584,296 640,240 880,480 640,720Z"/>
+</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_graphics.xml b/src/android/app/src/main/res/drawable/ic_graphics.xml
new file mode 100644
index 000000000..2fdb5a4d6
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_graphics.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960">
+ <path
+ android:fillColor="?attr/colorControlNormal"
+ android:pathData="M160,840q-33,0 -56.5,-23.5T80,760v-560q0,-33 23.5,-56.5T160,120h560q33,0 56.5,23.5T800,200v80h80v80h-80v80h80v80h-80v80h80v80h-80v80q0,33 -23.5,56.5T720,840L160,840ZM160,760h560v-560L160,200v560ZM240,680h200v-160L240,520v160ZM480,400h160v-120L480,280v120ZM240,480h200v-200L240,280v200ZM480,680h160v-240L480,440v240ZM160,200v560,-560Z"/>
+</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_system_settings.xml b/src/android/app/src/main/res/drawable/ic_system_settings.xml
new file mode 100644
index 000000000..7701a2bab
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_system_settings.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960">
+ <path
+ android:fillColor="?attr/colorControlNormal"
+ android:pathData="M320,960q-17,0 -28.5,-11.5T280,920q0,-17 11.5,-28.5T320,880q17,0 28.5,11.5T360,920q0,17 -11.5,28.5T320,960ZM480,960q-17,0 -28.5,-11.5T440,920q0,-17 11.5,-28.5T480,880q17,0 28.5,11.5T520,920q0,17 -11.5,28.5T480,960ZM640,960q-17,0 -28.5,-11.5T600,920q0,-17 11.5,-28.5T640,880q17,0 28.5,11.5T680,920q0,17 -11.5,28.5T640,960ZM320,800q-33,0 -56.5,-23.5T240,720v-640q0,-33 23.5,-56.5T320,0h320q33,0 56.5,23.5T720,80v640q0,33 -23.5,56.5T640,800L320,800ZM320,720h320v-40L320,680v40ZM320,600h320v-400L320,200v400ZM320,120h320v-40L320,80v40ZM320,120v-40,40ZM320,720v-40,40Z"/>
+</vector>
diff --git a/src/android/app/src/main/res/layout-w600dp/fragment_about.xml b/src/android/app/src/main/res/layout-w600dp/fragment_about.xml
new file mode 100644
index 000000000..a26ffbc73
--- /dev/null
+++ b/src/android/app/src/main/res/layout-w600dp/fragment_about.xml
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/coordinator_about"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?attr/colorSurface">
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:id="@+id/appbar_about"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fitsSystemWindows="true">
+
+ <com.google.android.material.appbar.MaterialToolbar
+ android:id="@+id/toolbar_about"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ app:navigationIcon="@drawable/ic_back"
+ app:title="@string/about" />
+
+ </com.google.android.material.appbar.AppBarLayout>
+
+ <androidx.core.widget.NestedScrollView
+ android:id="@+id/scroll_about"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fadeScrollbars="false"
+ android:scrollbars="vertical"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+ <LinearLayout
+ android:id="@+id/content_about"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/image_logo"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ android:layout_gravity="center_horizontal"
+ android:padding="20dp"
+ android:src="@drawable/ic_yuzu_title" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingHorizontal="16dp"
+ android:paddingVertical="16dp">
+
+ <com.google.android.material.textview.MaterialTextView
+ style="@style/TextAppearance.Material3.TitleMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:text="@string/about"
+ android:textAlignment="viewStart" />
+
+ <com.google.android.material.textview.MaterialTextView
+ style="@style/TextAppearance.Material3.BodyMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="6dp"
+ android:text="@string/about_app_description"
+ android:textAlignment="viewStart" />
+
+ </LinearLayout>
+
+ <com.google.android.material.divider.MaterialDivider
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="20dp" />
+
+ <LinearLayout
+ android:id="@+id/button_contributors"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?attr/selectableItemBackground"
+ android:orientation="vertical"
+ android:paddingHorizontal="16dp"
+ android:paddingVertical="16dp">
+
+ <com.google.android.material.textview.MaterialTextView
+ style="@style/TextAppearance.Material3.TitleMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:text="@string/contributors"
+ android:textAlignment="viewStart" />
+
+ <com.google.android.material.textview.MaterialTextView
+ style="@style/TextAppearance.Material3.BodyMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="6dp"
+ android:text="@string/contributors_description"
+ android:textAlignment="viewStart" />
+
+ </LinearLayout>
+
+ <com.google.android.material.divider.MaterialDivider
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="20dp" />
+
+ <LinearLayout
+ android:id="@+id/button_licenses"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?attr/selectableItemBackground"
+ android:orientation="vertical"
+ android:paddingHorizontal="16dp"
+ android:paddingVertical="16dp">
+
+ <com.google.android.material.textview.MaterialTextView
+ style="@style/TextAppearance.Material3.TitleMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:text="@string/licenses"
+ android:textAlignment="viewStart" />
+
+ <com.google.android.material.textview.MaterialTextView
+ style="@style/TextAppearance.Material3.BodyMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="6dp"
+ android:text="@string/licenses_description"
+ android:textAlignment="viewStart" />
+
+ </LinearLayout>
+
+ <com.google.android.material.divider.MaterialDivider
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="20dp" />
+
+ <LinearLayout
+ android:id="@+id/button_build_hash"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?attr/selectableItemBackground"
+ android:orientation="vertical"
+ android:paddingHorizontal="16dp"
+ android:paddingVertical="16dp">
+
+ <com.google.android.material.textview.MaterialTextView
+ style="@style/TextAppearance.Material3.TitleMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:text="@string/build"
+ android:textAlignment="viewStart" />
+
+ <com.google.android.material.textview.MaterialTextView
+ android:id="@+id/text_build_hash"
+ style="@style/TextAppearance.Material3.BodyMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="6dp"
+ android:textAlignment="viewStart"
+ tools:text="abc123" />
+
+ </LinearLayout>
+
+ <com.google.android.material.divider.MaterialDivider
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="20dp" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="40dp"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="16dp"
+ android:gravity="center_horizontal"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/button_discord"
+ style="?attr/materialIconButtonStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ app:icon="@drawable/ic_discord"
+ app:iconGravity="textEnd"
+ app:iconSize="24dp"
+ app:iconTint="?attr/colorOnSurface" />
+
+ <Button
+ android:id="@+id/button_website"
+ style="?attr/materialIconButtonStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ app:icon="@drawable/ic_website"
+ app:iconGravity="textEnd"
+ app:iconSize="24dp"
+ app:iconTint="?attr/colorOnSurface" />
+
+ <Button
+ android:id="@+id/button_github"
+ style="?attr/materialIconButtonStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ app:icon="@drawable/ic_github"
+ app:iconGravity="textEnd"
+ app:iconSize="24dp"
+ app:iconTint="?attr/colorOnSurface" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ </androidx.core.widget.NestedScrollView>
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/src/android/app/src/main/res/layout/card_home_option.xml b/src/android/app/src/main/res/layout/card_home_option.xml
index 6e8a232f9..cb667c928 100644
--- a/src/android/app/src/main/res/layout/card_home_option.xml
+++ b/src/android/app/src/main/res/layout/card_home_option.xml
@@ -6,8 +6,8 @@
android:id="@+id/option_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginVertical="12dp"
- android:layout_marginHorizontal="16dp"
+ android:layout_marginBottom="24dp"
+ android:layout_marginHorizontal="12dp"
android:background="?attr/selectableItemBackground"
android:backgroundTint="?attr/colorSurfaceVariant"
android:clickable="true"
diff --git a/src/android/app/src/main/res/layout/fragment_about.xml b/src/android/app/src/main/res/layout/fragment_about.xml
index 3e1d98451..a24f5230e 100644
--- a/src/android/app/src/main/res/layout/fragment_about.xml
+++ b/src/android/app/src/main/res/layout/fragment_about.xml
@@ -38,17 +38,17 @@
<ImageView
android:id="@+id/image_logo"
- android:layout_width="250dp"
- android:layout_height="250dp"
- android:layout_marginTop="20dp"
+ android:layout_width="150dp"
+ android:layout_height="150dp"
+ android:layout_marginTop="24dp"
+ android:layout_marginBottom="28dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_yuzu_title" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginHorizontal="20dp"
- android:layout_marginTop="28dp" />
+ android:layout_marginHorizontal="20dp" />
<LinearLayout
android:layout_width="match_parent"
diff --git a/src/android/app/src/main/res/layout/fragment_emulation.xml b/src/android/app/src/main/res/layout/fragment_emulation.xml
index 750ce094a..5252adf54 100644
--- a/src/android/app/src/main/res/layout/fragment_emulation.xml
+++ b/src/android/app/src/main/res/layout/fragment_emulation.xml
@@ -134,18 +134,21 @@
<FrameLayout
android:id="@+id/overlay_container"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
- <TextView
+ <com.google.android.material.textview.MaterialTextView
android:id="@+id/show_fps_text"
+ style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:clickable="false"
android:focusable="false"
- android:shadowColor="@android:color/black"
+ android:paddingHorizontal="20dp"
android:textColor="@android:color/white"
- android:textSize="12sp"
+ android:shadowColor="@android:color/black"
+ android:shadowRadius="3"
tools:ignore="RtlHardcoded" />
</FrameLayout>
diff --git a/src/android/app/src/main/res/layout/fragment_home_settings.xml b/src/android/app/src/main/res/layout/fragment_home_settings.xml
index 1cb421dcb..d84093ba3 100644
--- a/src/android/app/src/main/res/layout/fragment_home_settings.xml
+++ b/src/android/app/src/main/res/layout/fragment_home_settings.xml
@@ -14,13 +14,14 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:background="?attr/colorSurface">
+ android:background="?attr/colorSurface"
+ android:paddingHorizontal="8dp">
<ImageView
android:id="@+id/logo_image"
- android:layout_width="128dp"
- android:layout_height="128dp"
- android:layout_margin="64dp"
+ android:layout_width="96dp"
+ android:layout_height="96dp"
+ android:layout_marginVertical="32dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_yuzu_full" />
diff --git a/src/android/app/src/main/res/layout/fragment_search.xml b/src/android/app/src/main/res/layout/fragment_search.xml
index b8d54d947..efdfd7047 100644
--- a/src/android/app/src/main/res/layout/fragment_search.xml
+++ b/src/android/app/src/main/res/layout/fragment_search.xml
@@ -127,6 +127,7 @@
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingVertical="4dp"
+ app:checkedChip="@id/chip_recently_played"
app:chipSpacingHorizontal="12dp"
app:singleLine="true"
app:singleSelection="true">
diff --git a/src/android/app/src/main/res/layout/list_item_setting.xml b/src/android/app/src/main/res/layout/list_item_setting.xml
index f1037a740..544280e75 100644
--- a/src/android/app/src/main/res/layout/list_item_setting.xml
+++ b/src/android/app/src/main/res/layout/list_item_setting.xml
@@ -10,41 +10,59 @@
android:focusable="true"
android:gravity="center_vertical"
android:minHeight="72dp"
- android:padding="@dimen/spacing_large">
+ android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:orientation="horizontal">
- <com.google.android.material.textview.MaterialTextView
- android:id="@+id/text_setting_name"
- style="@style/TextAppearance.Material3.HeadlineMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAlignment="viewStart"
- android:textSize="16sp"
- app:lineHeight="22dp"
- tools:text="Setting Name" />
-
- <com.google.android.material.textview.MaterialTextView
- android:id="@+id/text_setting_description"
- style="@style/TextAppearance.Material3.BodySmall"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/spacing_small"
- android:textAlignment="viewStart"
- tools:text="@string/app_disclaimer" />
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="24dp"
+ android:layout_gravity="center_vertical"
+ android:visibility="gone"
+ app:tint="?attr/colorOnSurface" />
- <com.google.android.material.textview.MaterialTextView
- android:id="@+id/text_setting_value"
- style="@style/TextAppearance.Material3.LabelMedium"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/spacing_small"
- android:textAlignment="viewStart"
- android:textStyle="bold"
- tools:text="1x" />
+ android:orientation="vertical">
+
+ <com.google.android.material.textview.MaterialTextView
+ android:id="@+id/text_setting_name"
+ style="@style/TextAppearance.Material3.HeadlineMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="viewStart"
+ android:textSize="17sp"
+ app:lineHeight="22dp"
+ tools:text="Setting Name" />
+
+ <com.google.android.material.textview.MaterialTextView
+ android:id="@+id/text_setting_description"
+ style="@style/TextAppearance.Material3.BodySmall"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/spacing_small"
+ android:textAlignment="viewStart"
+ tools:text="@string/app_disclaimer" />
+
+ <com.google.android.material.textview.MaterialTextView
+ android:id="@+id/text_setting_value"
+ style="@style/TextAppearance.Material3.LabelMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/spacing_small"
+ android:textAlignment="viewStart"
+ android:textStyle="bold"
+ android:textSize="13sp"
+ tools:text="1x" />
+
+ </LinearLayout>
</LinearLayout>
diff --git a/src/android/app/src/main/res/layout/list_item_setting_switch.xml b/src/android/app/src/main/res/layout/list_item_setting_switch.xml
index a5767adee..a8f5aff78 100644
--- a/src/android/app/src/main/res/layout/list_item_setting_switch.xml
+++ b/src/android/app/src/main/res/layout/list_item_setting_switch.xml
@@ -8,9 +8,7 @@
android:clickable="true"
android:focusable="true"
android:minHeight="72dp"
- android:paddingVertical="@dimen/spacing_large"
- android:paddingStart="@dimen/spacing_large"
- android:paddingEnd="24dp">
+ android:padding="16dp">
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_widget"
@@ -24,7 +22,7 @@
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerVertical="true"
- android:layout_marginEnd="@dimen/spacing_large"
+ android:layout_marginEnd="24dp"
android:layout_toStartOf="@+id/switch_widget"
android:gravity="center_vertical"
android:orientation="vertical">
@@ -35,7 +33,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
- android:textSize="16sp"
+ android:textSize="17sp"
app:lineHeight="28dp"
tools:text="@string/frame_limit_enable" />
diff --git a/src/android/app/src/main/res/layout/list_item_settings_header.xml b/src/android/app/src/main/res/layout/list_item_settings_header.xml
index cf85bc0da..21276b19e 100644
--- a/src/android/app/src/main/res/layout/list_item_settings_header.xml
+++ b/src/android/app/src/main/res/layout/list_item_settings_header.xml
@@ -7,7 +7,8 @@
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingHorizontal="@dimen/spacing_large"
- android:paddingVertical="16dp"
+ android:paddingTop="16dp"
+ android:paddingBottom="8dp"
android:textAlignment="viewStart"
android:textColor="?attr/colorPrimary"
android:textStyle="bold"
diff --git a/src/android/app/src/main/res/resources.properties b/src/android/app/src/main/res/resources.properties
new file mode 100644
index 000000000..467b3efec
--- /dev/null
+++ b/src/android/app/src/main/res/resources.properties
@@ -0,0 +1 @@
+unqualifiedResLocale=en-US
diff --git a/src/android/app/src/main/res/values-ar/strings.xml b/src/android/app/src/main/res/values-ar/strings.xml
new file mode 100644
index 000000000..07dffffe8
--- /dev/null
+++ b/src/android/app/src/main/res/values-ar/strings.xml
@@ -0,0 +1,385 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
+
+ <string name="emulation_notification_channel_name">المحاكي نشط</string>
+ <string name="emulation_notification_channel_description">اظهار اشعار دائم عندما يكون المحاكي نشطاً</string>
+ <string name="emulation_notification_running">يوزو يعمل</string>
+ <string name="notice_notification_channel_name">الإشعارات والأخطاء</string>
+ <string name="notice_notification_channel_description">اظهار اشعار عند حصول اي مشكلة.</string>
+ <string name="notification_permission_not_granted">لم يتم منح إذن الإشعار</string>
+
+ <!-- Setup strings -->
+ <string name="welcome">مرحبًا</string>
+ <string name="welcome_description">والانتقال إلى المحاكاة <b>يوزو</b> تعرف على كيفية إعداد.</string>
+ <string name="get_started">لنبدأ</string>
+ <string name="keys">المفاتيح</string>
+ <string name="keys_description">اختر ملف &lt;b>prod.keys&lt;/b> من الزر ادناه</string>
+ <string name="select_keys">إختيار المفاتيح</string>
+ <string name="games">الألعاب</string>
+ <string name="games_description">اختر مجلد &lt;b>العابك&lt;/b> من الزر ادناه.</string>
+ <string name="done">إنهاء</string>
+ <string name="done_description">كل شيء جاهز./n استمتع بألعابك!</string>
+ <string name="text_continue">استمر</string>
+ <string name="next">التالي</string>
+ <string name="back">عودة</string>
+ <string name="add_games">إضافة ألعاب</string>
+ <string name="add_games_description">إختار مجلد ألعابك</string>
+ <string name="step_complete">مكتمل</string>
+
+ <!-- Home strings -->
+ <string name="home_games">الألعاب</string>
+ <string name="home_search">البحث</string>
+ <string name="home_settings">الإعدادات</string>
+ <string name="empty_gamelist">لم يتم العثور على ملفات او لم يتم تحديد مسار العاب.</string>
+ <string name="search_and_filter_games">بحث وتصفية الألعاب</string>
+ <string name="select_games_folder">تحديد مجلد الألعاب</string>
+ <string name="select_games_folder_description">يسمح لـ يوزو بملء قائمة الألعاب</string>
+ <string name="add_games_warning">تخطُ اختيار مجلد الالعاب؟</string>
+ <string name="add_games_warning_description">لن يتم عرض الألعاب في قائمة الألعاب إذا لم يتم تحديد مجلد</string>
+ <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
+ <string name="home_search_games">البحث عن ألعاب</string>
+ <string name="search_settings">إعدادات البحث</string>
+ <string name="games_dir_selected">تم تحديد مجلد الألعاب</string>
+ <string name="install_prod_keys">تثبيت prod.keys</string>
+ <string name="install_prod_keys_description">مطلوب لفك تشفير ألعاب البيع بالتجزئة</string>
+ <string name="install_prod_keys_warning">تخطي إضافة المفاتيح؟</string>
+ <string name="install_prod_keys_warning_description">مطلوب مفاتيح صالحة لمحاكاة ألعاب البيع بالتجزئة. ستعمل تطبيقات البيرة المنزلية فقط إذا تابعت</string>
+ <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
+ <string name="notifications">التنبيهات</string>
+ <string name="notifications_description">امنح إذن الإشعار باستخدام الزر أدناه</string>
+ <string name="give_permission">منح الإذن</string>
+ <string name="notification_warning">تخطي منح إذن الإشعارات؟</string>
+ <string name="notification_warning_description">لن يتمكن يوزو من إشعارك بالمعلومات المهمة</string>
+ <string name="permission_denied">تم رفض الإذن</string>
+ <string name="permission_denied_description">لقد رفضت هذا الإذن عدة مرات ويتعين عليك الآن منحه يدويًا في إعدادات النظام</string>
+ <string name="about">حول</string>
+ <string name="about_description">بناء الإصدار، والاعتمادات، وأكثر من ذلك</string>
+ <string name="warning_help">مساعدة</string>
+ <string name="warning_skip">تخطي</string>
+ <string name="warning_cancel">إلغاء</string>
+ <string name="install_amiibo_keys">تثبيت مفاتيح أميبو</string>
+ <string name="install_amiibo_keys_description">مطلوب لاستخدام أميبو في اللعبة</string>
+ <string name="invalid_keys_file">تم تحديد ملف مفاتيح غير صالح</string>
+ <string name="install_keys_success">تم تثبيت المفاتيح بنجاح</string>
+ <string name="reading_keys_failure">خطأ في قراءة مفاتيح التشفير</string>
+ <string name="invalid_keys_error">مفاتيح التشفير غير صالحة</string>
+ <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
+ <string name="install_keys_failure_description">الملف المحدد غير صحيح أو تالف. يرجى إعادة المفاتيح الخاصة بك</string>
+ <string name="install_gpu_driver">GPU تثبيت برنامج تشغيل</string>
+ <string name="install_gpu_driver_description">قم بتثبيت برامج تشغيل بديلة للحصول على أداء أو دقة أفضل</string>
+ <string name="advanced_settings">إعدادات متقدمة</string>
+ <string name="advanced_settings_game">إعدادات متقدمة: %1$s</string>
+ <string name="settings_description">تكوين إعدادات المحاكي</string>
+ <string name="search_recently_played">لعبت مؤخرا</string>
+ <string name="search_recently_added">أضيف مؤخرا</string>
+ <string name="search_retail">بيع بالتجزئة</string>
+ <string name="search_homebrew">البيرة المنزلية</string>
+ <string name="open_user_folder">فتح مجلد يوزو</string>
+ <string name="open_user_folder_description">إدارة ملفات يوزو الداخلية</string>
+ <string name="theme_and_color_description">تعديل مظهر التطبيق</string>
+ <string name="no_file_manager">لم يتم العثور على مدير الملفات</string>
+ <string name="notification_no_directory_link">لا يمكن فتح مجلد يوزو</string>
+ <string name="notification_no_directory_link_description">الرجاء تحديد موقع مجلد المستخدم باستخدام اللوحة الجانبية لمدير الملفات يدويًا</string>
+ <string name="manage_save_data">إدارة حفظ البيانات</string>
+ <string name="manage_save_data_description">حفظ البيانات التي تم العثور عليها. يرجى اختيار أحد الخيارات التالية</string>
+ <string name="import_export_saves_description">استيراد أو تصدير ملفات الحفظ</string>
+ <string name="save_file_imported_success">تم الاستيراد بنجاح</string>
+ <string name="save_file_invalid_zip_structure">بنية مجلد الحفظ غير صالحة</string>
+ <string name="save_file_invalid_zip_structure_description">يجب أن يكون اسم المجلد الفرعي الأول هو معرف عنوان اللعبة.</string>
+ <string name="import_saves">استيراد</string>
+ <string name="export_saves">تصدير</string>
+ <string name="install_firmware">تثبيت البرامج الثابتة</string>
+ <string name="firmware_installing">تثبيت البرامج الثابتة</string>
+ <string name="firmware_installed_success">تم تثبيت البرامج الثابتة بنجاح</string>
+ <string name="firmware_installed_failure">فشل تثبيت البرامج الثابتة</string>
+ <string name="share_log">مشاركة سجلات التصحيح</string>
+ <string name="share_log_description">مشاركة ملف سجل يوزو لتصحيح المشكلات</string>
+ <string name="share_log_missing">لم يتم العثور على ملف السجل</string>
+ <string name="install_game_content">تثبيت محتوى اللعبة</string>
+ <string name="install_game_content_description">DLC قم بتثبيت تحديثات اللعبة أو</string>
+ <string name="installing_game_content">جارٍ تثبيت المحتوى</string>
+ <string name="install_game_content_failure_base">لا يُسمح بتثبيت الألعاب الأساسية لتجنب التعارضات المحتملة.</string>
+ <string name="install_game_content_success_install">%1$d تم التثبيت بنجاح</string>
+ <string name="install_game_content_success_overwrite">%1$d تمت الكتابة فوقه بنجاح</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">برامج التشغيل المخصصة غير مدعومة</string>
+ <string name="custom_driver_not_supported_description">تحميل برنامج التشغيل المخصص غير معتمد حاليًا لهذا الجهاز.\nحدد هذا الخيار مرة أخرى في المستقبل لمعرفة ما إذا تمت إضافة الدعم!</string>
+ <string name="manage_yuzu_data">إدارة بيانات يوزو</string>
+ <string name="manage_yuzu_data_description">استيراد/تصدير البرامج الثابتة والمفاتيح وبيانات المستخدم والمزيد!</string>
+ <string name="share_save_file">مشاركة ملف الحفظ</string>
+ <string name="export_save_failed">فشل تصدير الحفظ</string>
+
+ <string name="copied_to_clipboard">نسخ إلى الحافظة</string>
+ <string name="about_app_description">محاكي سويتش مفتوح المصدر</string>
+ <string name="contributors">المساهمين</string>
+ <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">المشاريع التي تجعل تطبيق يوزو لنظام أندرويد ممكنًا</string>
+ <string name="build">البناء</string>
+ <string name="user_data">بيانات المستخدم</string>
+ <string name="exporting_user_data">جارٍ تصدير بيانات المستخدم</string>
+ <string name="importing_user_data">جارٍ استيراد بيانات المستخدم</string>
+ <string name="import_user_data">استيراد بيانات المستخدم</string>
+ <string name="invalid_yuzu_backup">نسخة احتياطية يوزو غير صالحة</string>
+ <string name="user_data_export_success">تم تصدير بيانات المستخدم بنجاح</string>
+ <string name="user_data_import_success">تم استيراد بيانات المستخدم بنجاح</string>
+ <string name="user_data_export_cancelled">تم إلغاء التصدير</string>
+ <string name="support_link">https://discord.gg/u77vRWY</string>
+ <string name="website_link">https://yuzu-emu.org/</string>
+ <string name="github_link">https://github.com/yuzu-emu</string>
+
+ <!-- Early access upgrade strings -->
+ <string name="early_access">الوصول المبكر</string>
+ <string name="get_early_access">احصل على الوصول المبكر</string>
+ <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
+ <string name="get_early_access_description">الميزات المتطورة، والوصول المبكر إلى التحديثات، وأكثر من ذلك</string>
+ <string name="early_access_benefits">مزايا الوصول المبكر</string>
+ <string name="cutting_edge_features">ميزات متطورة</string>
+ <string name="early_access_updates">الوصول المبكر إلى التحديثات</string>
+ <string name="no_manual_installation">لا يوجد التثبيت اليدوي</string>
+ <string name="prioritized_support">الدعم ذو الأولوية</string>
+ <string name="helping_game_preservation">المساعدة في الحفاظ على اللعبة</string>
+ <string name="our_eternal_gratitude">امتناننا الأبدي</string>
+ <string name="are_you_interested">هل انت مهتم؟</string>
+
+ <!-- General settings strings -->
+ <string name="frame_limit_enable">الحد من السرعة</string>
+ <string name="frame_limit_enable_description">يحد من سرعة المحاكاة بنسبة محددة من السرعة العادية</string>
+ <string name="frame_limit_slider">الحد من السرعة في المئة</string>
+ <string name="frame_limit_slider_description">يحدد النسبة المئوية للحد من سرعة المحاكاة. 100% هي السرعة الطبيعية. ستؤدي القيم الأعلى أو الأدنى إلى زيادة أو تقليل حد السرعة.</string>
+ <string name="cpu_accuracy">دقة وحدة المعالجة المركزية</string>
+ <string name="value_with_units">%1$s%2$s</string>
+
+ <!-- System settings strings -->
+ <string name="use_docked_mode">وضع الإرساء</string>
+ <string name="use_docked_mode_description">زيادة الدقة، وانخفاض الأداء. يتم استخدام الوضع المحمول عند تعطيله، مما يؤدي إلى خفض الدقة وزيادة الأداء.</string>
+ <string name="emulated_region">المنطقة التي تمت محاكاتها</string>
+ <string name="emulated_language">لغة المحاكاه</string>
+ <string name="select_rtc_date">حدد التاريخ و الساعة في الوقت الحقيقي</string>
+ <string name="select_rtc_time">حدد وقت الساعة في الوقت الفعلي</string>
+ <string name="use_custom_rtc">ساعة مخصصة في الوقت الحقيقي</string>
+ <string name="use_custom_rtc_description">يسمح لك بتعيين ساعة مخصصة في الوقت الفعلي منفصلة عن وقت النظام الحالي لديك</string>
+ <string name="set_custom_rtc">تعيين ساعة مخصصة في الوقت الحقيقي</string>
+
+ <!-- Graphics settings strings -->
+ <string name="renderer_accuracy">مستوى الدقة</string>
+ <string name="renderer_resolution">(Handheld/Docked) الدقة</string>
+ <string name="renderer_vsync">VSync وضع</string>
+ <string name="renderer_screen_layout">الاتجاه</string>
+ <string name="renderer_aspect_ratio">تناسب الابعاد</string>
+ <string name="renderer_anti_aliasing">طريقة مكافحة التعرج</string>
+ <string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
+ <string name="renderer_asynchronous_shaders_description">يجمع التظليل بشكل غير متزامن، مما يقلل من التأتأة ولكنه قد يؤدي إلى حدوث بعض الأخطاء.</string>
+ <string name="renderer_reactive_flushing">استخدم التنظيف التفاعلي</string>
+ <string name="renderer_reactive_flushing_description">تحسين دقة العرض في بعض الألعاب على حساب الأداء</string>
+ <string name="use_disk_shader_cache_description">يقلل من التأتأة عن طريق تخزين وتحميل التظليلات التي تم إنشاؤها محليًا.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">وحدة المعالج المركزية</string>
+ <string name="cpu_debug_mode">تصحيح أخطاء وحدة المعالجة المركزية</string>
+ <string name="cpu_debug_mode_description">يضع وحدة المعالجة المركزية في وضع التصحيح البطيء.</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">تصحيح الأخطاء الرسومية</string>
+ <string name="renderer_debug_description">يضبط واجهة برمجة تطبيقات الرسومات على وضع تصحيح الأخطاء البطيء.</string>
+ <string name="fastmem">Fastmem</string>
+
+ <!-- Audio settings strings -->
+ <string name="audio_output_engine">محرك الإخراج</string>
+ <string name="audio_volume">حجم</string>
+ <string name="audio_volume_description">يحدد حجم إخراج الصوت</string>
+
+ <!-- Miscellaneous -->
+ <string name="slider_default">افتراضي</string>
+ <string name="ini_saved">الإعدادات المحفوظة</string>
+ <string name="gameid_saved">الإعدادات المحفوظة لـ %1$s</string>
+ <string name="unimplemented_menu">القائمة غير المنفذة</string>
+ <string name="loading">جاري تحميل</string>
+ <string name="shutting_down">إيقاف تشغيل</string>
+ <string name="reset_setting_confirmation">هل تريد إعادة تعيين هذا الإعداد مرة أخرى إلى قيمته الافتراضية؟</string>
+ <string name="reset_to_default">إعادة تعيين إلى الافتراضي</string>
+ <string name="reset_all_settings">إعادة تعيين جميع الإعدادات؟</string>
+ <string name="reset_all_settings_description">سيتم إعادة تعيين كافة الإعدادات المتقدمة إلى تكوينها الافتراضي. هذا لا يمكن التراجع عنها.</string>
+ <string name="settings_reset">إعادة تعيين الأعدادات</string>
+ <string name="close">إغلاق</string>
+ <string name="learn_more">معرفة المزيد</string>
+ <string name="auto">تلقائي</string>
+ <string name="submit">إرسال</string>
+ <string name="string_null">قيمه خاليه</string>
+ <string name="string_import">استيراد</string>
+ <string name="export">تصدير</string>
+ <string name="export_failed">فشل التصدير</string>
+ <string name="import_failed">فشل الاستيراد</string>
+ <string name="cancelling">إلغاء</string>
+
+ <!-- GPU driver installation -->
+ <string name="select_gpu_driver">GPU حدد برنامج تشغيل</string>
+ <string name="select_gpu_driver_title">الحالي الخاص بك؟ GPU هل ترغب في استبدال برنامج تشغيل</string>
+ <string name="select_gpu_driver_install">تثبيت</string>
+ <string name="select_gpu_driver_default">افتراضي</string>
+ <string name="select_gpu_driver_use_default">يستخدم تعريف معالج الرسوميات الافتراضي</string>
+ <string name="select_gpu_driver_error">تم تحديد برنامج تشغيل غير صالح ، باستخدام النظام الافتراضي</string>
+ <string name="system_gpu_driver">تعريف معالج الرسوميات الخاص بالنظام</string>
+ <string name="installing_driver">جارٍ تثبيت برنامج التشغيل…</string>
+
+ <!-- Preferences Screen -->
+ <string name="preferences_settings">إعدادات</string>
+ <string name="preferences_general">عام</string>
+ <string name="preferences_system">النظام</string>
+ <string name="preferences_graphics">الرسوميات</string>
+ <string name="preferences_audio">الصوت</string>
+ <string name="preferences_theme">السمة واللون</string>
+ <string name="preferences_debug">تصحيح الأخطاء</string>
+
+ <!-- ROM loading errors -->
+ <string name="loader_error_encrypted">الخاص بك ROM تم تشفير</string>
+ <string name="loader_error_video_core">حدث خطأ أثناء تهيئة مركز الفيديو</string>
+ <string name="loader_error_invalid_format">ROM غير قادر على تحميل</string>
+ <string name="loader_error_file_not_found">غير موجود ROM ملف</string>
+
+ <!-- Emulation Menu -->
+ <string name="emulation_exit">الخروج من المحاكاة</string>
+ <string name="emulation_done">منجز</string>
+ <string name="emulation_fps_counter">عداد إطار/ثانية</string>
+ <string name="emulation_toggle_controls">تبديل عناصر التحكم</string>
+ <string name="emulation_rel_stick_center">مركز العصا النسبي</string>
+ <string name="emulation_dpad_slide">مزلاق أزرار الاتجاهات</string>
+ <string name="emulation_haptics">الاهتزازات الديناميكية</string>
+ <string name="emulation_show_overlay">عرض التراكب</string>
+ <string name="emulation_toggle_all">تبديل الكل</string>
+ <string name="emulation_control_adjust">ضبط التراكب</string>
+ <string name="emulation_control_scale">حجم</string>
+ <string name="emulation_control_opacity">العتامه</string>
+ <string name="emulation_touch_overlay_reset">إعادة تعيين التراكب</string>
+ <string name="emulation_touch_overlay_edit">تحرير التراكب</string>
+ <string name="emulation_pause">إيقاف المحاكاة مؤقتًا</string>
+ <string name="emulation_unpause">إلغاء الإيقاف المؤقت للمضاهاة</string>
+ <string name="emulation_input_overlay">خيارات التراكب</string>
+
+ <string name="load_settings">جارٍ تحميل الإعدادات</string>
+
+ <!-- Software keyboard -->
+ <string name="software_keyboard">لوحة المفاتيح البرمجية</string>
+
+ <!-- Errors and warnings -->
+ <string name="abort_button">إلغاء</string>
+ <string name="continue_button">استمر</string>
+ <string name="system_archive_not_found">لم يتم العثور على أرشيف النظام</string>
+ <string name="system_archive_general">أرشيف النظام</string>
+ <string name="save_load_error">خطأ في الحفظ/التحميل</string>
+ <string name="fatal_error">خطا فادح</string>
+ <string name="performance_warning">سيؤدي إيقاف تشغيل هذا الإعداد إلى تقليل أداء المحاكاة بشكل ملحوظ! للحصول على أفضل تجربة، يوصى بترك هذا الإعداد ممكنًا.</string>
+ <string name="memory_formatted">%1$s %2$s</string>
+ <string name="no_game_present">لا توجد لعبة قابلة للتمهيد</string>
+
+ <!-- Region Names -->
+ <string name="region_japan">اليابان</string>
+ <string name="region_usa">الولايات المتحدة الأمريكية</string>
+ <string name="region_europe">أوروبا</string>
+ <string name="region_australia">أستراليا</string>
+ <string name="region_china">الصين</string>
+ <string name="region_korea">كوريا</string>
+ <string name="region_taiwan">تايوان</string>
+
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
+
+ <!-- Renderer APIs -->
+ <string name="renderer_vulkan">Vulkan</string>
+ <string name="renderer_none">لاشيء</string>
+
+ <!-- Renderer Accuracy -->
+ <string name="renderer_accuracy_normal">عادي</string>
+ <string name="renderer_accuracy_high">عالي</string>
+ <string name="renderer_accuracy_extreme">Extreme (بطيء)</string>
+
+ <!-- Resolutions -->
+ <string name="resolution_half">0.5X (360p/540p)</string>
+ <string name="resolution_three_quarter">0.75X (540p/810p)</string>
+ <string name="resolution_one">1X (720p/1080p)</string>
+ <string name="resolution_two">2X (1440p/2160p) (بطيء)</string>
+ <string name="resolution_three">3X (2160p/3240p) (بطيء)</string>
+ <string name="resolution_four">4X (2880p/4320p) (بطيء)</string>
+
+ <!-- Renderer VSync -->
+ <string name="renderer_vsync_immediate">Immediate (Off)</string>
+ <string name="renderer_vsync_mailbox">Mailbox</string>
+ <string name="renderer_vsync_fifo">FIFO (On)</string>
+ <string name="renderer_vsync_fifo_relaxed">FIFO Relaxed</string>
+
+ <!-- Scaling Filters -->
+ <string name="scaling_filter_nearest_neighbor">Nearest Neighbor</string>
+ <string name="scaling_filter_bilinear">Bilinear</string>
+ <string name="scaling_filter_bicubic">Bicubic</string>
+ <string name="scaling_filter_gaussian">Gaussian</string>
+ <string name="scaling_filter_scale_force">ScaleForce</string>
+ <string name="scaling_filter_fsr">AMD FidelityFX™ Super Resolution</string>
+
+ <!-- Anti-Aliasing -->
+ <string name="anti_aliasing_none">لا شيء</string>
+ <string name="anti_aliasing_fxaa">FXAA</string>
+ <string name="anti_aliasing_smaa">SMAA</string>
+
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">افقي</string>
+ <string name="screen_layout_portrait">عمودي</string>
+ <string name="screen_layout_auto">تلقائي</string>
+
+ <!-- Aspect Ratios -->
+ <string name="ratio_default">(16:9) افتراضي</string>
+ <string name="ratio_force_four_three">4:3 فرض</string>
+ <string name="ratio_force_twenty_one_nine">21:9 فرض</string>
+ <string name="ratio_force_sixteen_ten">16:10 فرض</string>
+ <string name="ratio_stretch">تمتد إلى النافذة</string>
+
+ <!-- CPU Accuracy -->
+ <string name="cpu_accuracy_accurate">دقه</string>
+ <string name="cpu_accuracy_unsafe">غير آمن</string>
+ <string name="cpu_accuracy_paranoid">Paranoid (Slow)</string>
+
+ <!-- Gamepad Buttons -->
+ <string name="gamepad_d_pad">أزرار الاتجاهات</string>
+ <string name="gamepad_left_stick">العصا اليسرى</string>
+ <string name="gamepad_right_stick">العصا اليمنى</string>
+ <string name="gamepad_home">شاشة الإستقبال</string>
+ <string name="gamepad_screenshot">لقطة شاشة</string>
+
+ <!-- Disk shader cache -->
+ <string name="preparing_shaders">تحضير التظليل</string>
+ <string name="building_shaders">بناء التظليل</string>
+
+ <!-- Theme options -->
+ <string name="change_app_theme">تغيير سمة التطبيق</string>
+ <string name="theme_default">افتراضي</string>
+ <string name="theme_material_you">Material You</string>
+
+ <!-- Theme Modes -->
+ <string name="change_theme_mode">تغيير وضع السمة</string>
+ <string name="theme_mode_follow_system">اتبع النظام</string>
+ <string name="theme_mode_light">فاتح</string>
+ <string name="theme_mode_dark">غامق</string>
+
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
+ <!-- Black backgrounds theme -->
+ <string name="use_black_backgrounds">خلفيات سوداء</string>
+ <string name="use_black_backgrounds_description">عند استخدام المظهر الداكن، قم بتطبيق خلفيات سوداء.</string>
+
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">صورة داخل صورة</string>
+ <string name="picture_in_picture_description">تصغير النافذة عند وضعها في الخلفية</string>
+ <string name="pause">توقف</string>
+ <string name="play">تشغيل</string>
+ <string name="mute">كتم</string>
+ <string name="unmute">إلغاء الكتم</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">التراخيص</string>
+ <string name="license_fidelityfx_fsr_description">AMD ترقية عالية الجودة من</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-ckb/strings.xml b/src/android/app/src/main/res/values-ckb/strings.xml
new file mode 100644
index 000000000..d2e5fee19
--- /dev/null
+++ b/src/android/app/src/main/res/values-ckb/strings.xml
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
+
+ <string name="app_disclaimer">ئەم نەرمەکاڵایە یارییەکانی کۆنسۆلی نینتێندۆ سویچ کارپێدەکات. هیچ ناونیشانێکی یاری و کلیلی تێدا نییە..&lt;br /&gt;&lt;br /&gt;پێش ئەوەی دەست پێ بکەیت، تکایە شوێنی فایلی <![CDATA[<b> prod.keys </b>]]> دیاریبکە لە نێو کۆگای ئامێرەکەت.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">زیاتر فێربە</a>]]></string>
+ <string name="emulation_notification_channel_name">ئیمولەیشن کارایە</string>
+ <string name="emulation_notification_channel_description">ئاگادارکردنەوەیەکی بەردەوام نیشان دەدات کاتێک ئیمولەیشن کاردەکات.</string>
+ <string name="emulation_notification_running">یوزو کاردەکات</string>
+ <string name="notice_notification_channel_name">ئاگاداری و هەڵەکان</string>
+ <string name="notice_notification_channel_description">ئاگادارکردنەوەکان پیشان دەدات کاتێک شتێک بە هەڵەدا دەچێت.</string>
+ <string name="notification_permission_not_granted">مۆڵەتی ئاگادارکردنەوە نەدراوە!</string>
+
+ <!-- Setup strings -->
+ <string name="welcome">بەخێربێیت!</string>
+ <string name="welcome_description">فێربە چۆن &lt;b>yuzu&lt;/b> ڕێکبخەیت و بچییە ناو ئیمولەیشن.</string>
+ <string name="get_started">دەست پێبکە</string>
+ <string name="keys">کلیلەکان</string>
+ <string name="keys_description">فایلی &lt;b>prod.keys&lt;/b> هەڵبژێرە بە دوگمەی خوارەوە.</string>
+ <string name="select_keys">کلیلەکان هەڵبژێرە</string>
+ <string name="games">یاریەکان</string>
+ <string name="games_description">فۆڵدەری &lt;b>Games&lt;/b> هەڵبژێرە بە دوگمەی خوارەوە.</string>
+ <string name="done">تەواو</string>
+ <string name="done_description">تۆ تەواو ئامادەیت.\nچێژ لە یارییەکانت وەربگرە!</string>
+ <string name="text_continue">بەردەوام بوون</string>
+ <string name="next">دواتر</string>
+ <string name="back">گەڕانەوە</string>
+ <string name="add_games">زیادکردنی یاری</string>
+ <string name="add_games_description">فۆڵدەری یارییەکانت هەڵبژێرە</string>
+ <!-- Home strings -->
+ <string name="home_games">یاریەکان</string>
+ <string name="home_search">گەڕان</string>
+ <string name="home_settings">ڕێکخستنەکان</string>
+ <string name="empty_gamelist">تا ئێستا هیچ فایلێک نەدۆزراوەتەوە یان هیچ ناونیشانێکی یاری هەڵنەبژێردراوە.</string>
+ <string name="search_and_filter_games">گەڕان و فلتەرکردنی یارییەکان</string>
+ <string name="select_games_folder">فۆڵدەری یارییەکان هەڵبژێرە</string>
+ <string name="select_games_folder_description">ڕێگە بە یوزو دەدات بۆ پڕکردنەوەی لیستی یارییەکان</string>
+ <string name="add_games_warning">هەڵبژاردنی فۆڵدەری یارییەکان تێپەڕدەکەیت؟</string>
+ <string name="add_games_warning_description">یارییەکان لە لیستی یارییەکاندا پیشان نادرێن ئەگەر فۆڵدەرێک هەڵنەبژێردرێت.</string>
+ <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
+ <string name="home_search_games">گەڕان بەدوای یارییەکاندا</string>
+ <string name="games_dir_selected">ناونیشانی یارییەکان هەڵبژێردرا</string>
+ <string name="install_prod_keys">دابمەزرێنە prod.keys</string>
+ <string name="install_prod_keys_description">پێویستە بۆ کۆدکردنەوەى یارییە تاکەکەسییەکان</string>
+ <string name="install_prod_keys_warning">زیادکردنی کلیلەکان تێپەڕدەکەیت؟</string>
+ <string name="install_prod_keys_warning_description">کلیلی دروست پێویستە بۆ وەرگرتنی یارییەکانی تاکەکەسی. تەنها ئەپەکانی homebrew کاردەکەن ئەگەر بەردەوام بیت.</string>
+ <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
+ <string name="notifications">ئاگادارکردنەوەکان</string>
+ <string name="notifications_description">بە دوگمەی خوارەوە مۆڵەتی ئاگادارکردنەوەکە بدە.</string>
+ <string name="give_permission">مۆڵەت بدە</string>
+ <string name="notification_warning">پێدانی مۆڵەتی ئاگادارکردنەوە تێپەڕدەکەیت؟</string>
+ <string name="notification_warning_description">یوزو ناتوانێت لە زانیاری گرنگ ئاگادارت بکاتەوە.</string>
+ <string name="permission_denied">مۆڵەت پێدان ڕەتکرایەوە</string>
+ <string name="permission_denied_description">زۆر جار ئەم مۆڵەتەت ڕەتکردۆتەوە و ئێستا دەبێت بە دەستی ڕێگەپێدان بکەیت لە ڕێکخستنەکانی سیستەمدا.</string>
+ <string name="about">دەربارە</string>
+ <string name="about_description">وەشانی دروستکردن، بیتبێن و زۆر شتیتر</string>
+ <string name="warning_help">یارمەتی</string>
+ <string name="warning_skip">پەڕاندن</string>
+ <string name="warning_cancel">ڕەتکردنەوە</string>
+ <string name="install_amiibo_keys">دامەزراندنی کلیلی Amiibo</string>
+ <string name="install_amiibo_keys_description">پێویستە بۆ بەکارهێنانی Amiibo لە یاریدا</string>
+ <string name="invalid_keys_file">فایلی کلیلێکی نادروست هەڵبژێردرا</string>
+ <string name="install_keys_success">کلیلەکان بە سەرکەوتوویی دامەزران</string>
+ <string name="reading_keys_failure">هەڵە لە خوێندنەوەی کۆدکردنی کلیل</string>
+ <string name="install_prod_keys_failure_extension_description">دڵنیابەوە کە فایلی کلیلەکانت درێژکراوەی .keys ی هەیە و دووبارە هەوڵبدەرەوە.</string>
+ <string name="install_amiibo_keys_failure_extension_description">دڵنیابە کە فایلی کلیلەکانت درێژکراوەی .bin ی هەیە و دووبارە هەوڵبدەرەوە.</string>
+ <string name="invalid_keys_error">کلیلی کۆدکردنی نادروستە</string>
+ <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
+ <string name="install_keys_failure_description">فایلە هەڵبژێردراوەکە هەڵەیە یان تێکچووە. تکایە دووبارە کلیلەکانت دەربێنەوە.</string>
+ <string name="install_gpu_driver">دامەزراندنی وەگەڕخەری GPU</string>
+ <string name="install_gpu_driver_description">دامەزراندنی وەگەڕخەری بەدیل بۆ ئەوەی بە ئەگەرێکی زۆرەوە کارایی باشتر یان وردبینی هەبێت</string>
+ <string name="advanced_settings">ڕێکخستنە پێشکەوتووەکان</string>
+ <string name="settings_description">سازدانی ڕێکخستنەکانی ئیمولەیتەر</string>
+ <string name="search_recently_played">بەم دواییە یاری کردووە</string>
+ <string name="search_recently_added">بەم دواییە زیادکرا</string>
+ <string name="search_retail">بەتاک</string>
+ <string name="search_homebrew">هۆم بریو</string>
+ <string name="open_user_folder">کردنەوەی فۆڵدەری یوزو</string>
+ <string name="open_user_folder_description">بەڕێوەبردنی فایلە ناوخۆییەکانی یوزو</string>
+ <string name="theme_and_color_description">دەستکاری کردنی شێوازی ئەپەکە</string>
+ <string name="no_file_manager">هیچ فایل بەڕێوەبەرێک نەدۆزرایەوە</string>
+ <string name="notification_no_directory_link">نەتوانرا ناونیشانی یوزو بکرێتەوە</string>
+ <string name="notification_no_directory_link_description">تکایە شوێنی فۆڵدەری بەکارهێنەر لەگەڵ پانێڵی لایەنی فایل بەڕێوەبارەکان بە دەست بدۆزەرەوە.</string>
+ <string name="manage_save_data">بەڕێوەبردنی داتای پاشەکەوتکراو</string>
+ <string name="manage_save_data_description">داتای پاشەکەوتکراو دۆزراوە. تکایە لە خوارەوە بژاردەیەک هەڵبژێرە.</string>
+ <string name="import_export_saves_description">هاوردەکردن یان هەناردەکردنی فایلی پاشەکەوتکراو</string>
+ <string name="save_file_imported_success">بە سەرکەوتوویی هاوردە کرا</string>
+ <string name="save_file_invalid_zip_structure">پێکهاتەی شوێنی پاشەکەوتکراو نادروستە</string>
+ <string name="save_file_invalid_zip_structure_description">ناوی یەکەمی فۆڵدەر دەبێت ناسنامەی ناونیشانی یارییەکە بێت.</string>
+ <string name="import_saves">هاوردەکردن</string>
+ <string name="export_saves">هەناردەکردن</string>
+ <string name="install_firmware">دامەزراندنی پتەوواڵا</string>
+ <string name="install_firmware_description">پتەوواڵا دەبێت لە ئەرشیفی زیپدا بێت و پێویستە بۆ بووتکردنی هەندێک یاری</string>
+ <string name="firmware_installing">دامەزرانی پتەوواڵا</string>
+ <string name="firmware_installed_success">پتەوواڵا بە سەرکەوتوویی دامەزرا</string>
+ <string name="firmware_installed_failure">دامەزراندنی پتەوواڵا شکستی هێنا</string>
+ <string name="share_log">هاوبەشی پێکردنی لۆگەکانی چاککردنەوە</string>
+ <string name="share_log_description">فایلە لۆگەکەی یوزو هاوبەش بکە بۆ چاککردنی کێشەکان</string>
+ <string name="share_log_missing">هیچ فایلێکی لۆگ نەدۆزراوە</string>
+ <string name="install_game_content">دامەزراندنی ناوەڕۆکی یاری</string>
+ <string name="install_game_content_description">دامەزراندنی نوێکاری یارییەکان یان DLC</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <!-- About screen strings -->
+ <string name="gaia_is_not_real">گایا ڕاستەقینە نییە</string>
+ <string name="copied_to_clipboard">کۆپی کرا بۆ تەختەی نووسین</string>
+ <string name="about_app_description">ئیمۆلیتەرێکی سەرچاوە-کراوەی سویچ</string>
+ <string name="contributors">بەشداربووان</string>
+ <string name="contributors_description">دروستکراوە لەگەڵ \u2764 لەلایەن تیمەکەی یوزو</string>
+ <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">ئەو پڕۆژانەی کە یوزوی بۆ ئەندرۆید ڕەخساند</string>
+ <string name="build">بونیات</string>
+ <string name="support_link">https://discord.gg/u77vRWY</string>
+ <string name="website_link">https://yuzu-emu.org/</string>
+ <string name="github_link">https://github.com/yuzu-emu</string>
+
+ <!-- Early access upgrade strings -->
+ <string name="early_access">بەزوویی دەسپێگەشتن</string>
+ <string name="get_early_access">بەدەستهێنانی بەزوویی دەسپێگەشتن</string>
+ <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
+ <string name="get_early_access_description">تایبەتمەندییە پێشکەوتووەکان، بەزوویی دەستگەیشتن بە نوێکارییەکان و زۆر شتی تر</string>
+ <string name="early_access_benefits">سوودەکانی بەزوویی دەسپێگەشتن</string>
+ <string name="cutting_edge_features">تایبەتمەندییە پێشکەوتووەکان</string>
+ <string name="early_access_updates">زوو دەستگەیشتن بە نوێکارییەکان</string>
+ <string name="no_manual_installation">چیتر دامەزراندنی دەستی نییە</string>
+ <string name="prioritized_support">پشتگیری لە پێشینە</string>
+ <string name="helping_game_preservation">یارمەتیدانی پاراستنی یارییەکان</string>
+ <string name="our_eternal_gratitude">سوپاس و پێزانینی هەمیشەییمان</string>
+ <string name="are_you_interested">ئایا تۆ خوازیاریت؟</string>
+
+ <!-- General settings strings -->
+ <string name="frame_limit_enable">سنووردارکردنی خێرایی</string>
+ <string name="frame_limit_enable_description">خێرایی ئیمولەیشن سنووردار دەکات بۆ ڕێژەیەکی دیاریکراو لە خێرایی ئاسایی.</string>
+ <string name="frame_limit_slider">سنووردارکردنی لەسەدای خێرایی</string>
+ <string name="frame_limit_slider_description">ڕێژەی سەدی دیاری دەکات بۆ سنووردارکردنی خێرایی ئیمولەیشن. 100% خێرایی ئاساییە. بەهایی بەرزتر یان نزمتر دەبێتە هۆی زیاد یان کەمکردنەوەی سنووری خێرایی.</string>
+ <string name="cpu_accuracy">وردی CPU</string>
+ <!-- System settings strings -->
+ <string name="use_docked_mode">دۆخی دۆککراو</string>
+ <string name="use_docked_mode_description">ڕوونی زیاد دەکات، کارایی کەم دەکاتەوە. دۆخی دەستی بەکاردێت کاتێک لەکاردەخرێت، ئەمەش ڕوونی دادەبەزێنێت و کارایی زیاد دەکات.</string>
+ <string name="emulated_region">ناوچەی ئیمولەیشن</string>
+ <string name="emulated_language">زمانی ئیمولەیتەر</string>
+ <string name="select_rtc_date">هەڵبژاردنی بەرواری RTC</string>
+ <string name="select_rtc_time">هەڵبژاردنی کاتی RTC</string>
+ <string name="use_custom_rtc">RTCی تایبەتمەند</string>
+ <string name="use_custom_rtc_description">ڕێگەت پێدەدات کاتژمێرێکی کاتی ڕاستەقینەی تایبەتمەند دابنێیت کە جیاوازە لە کاتی ئێستای سیستەمەکەت.</string>
+ <string name="set_custom_rtc">دانانی RTCی تایبەتمەند</string>
+
+ <!-- Graphics settings strings -->
+ <string name="renderer_accuracy">ئاستی وردبینی</string>
+ <string name="renderer_resolution">ڕوونی (دۆخی دەستی/دۆخی دۆک)</string>
+ <string name="renderer_vsync">دۆخی VSync</string>
+ <string name="renderer_aspect_ratio">ڕێژەی ڕووبەری شاشە</string>
+ <string name="renderer_scaling_filter">فلتەری گونجاندنی پەنجەرە</string>
+ <string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
+ <string name="renderer_force_max_clock">ناچاریکردن بۆ زۆرترین کاتژمێر (تەنها ئەدرینۆ)</string>
+ <string name="renderer_force_max_clock_description">GPU ناچار دەکات بە زۆرترین کاتژمێر کاربکات (هێشتا سنووردارکردنی گەرمی جێبەجێ دەکرێت).</string>
+ <string name="renderer_asynchronous_shaders">بەکارهێنانی سێبەری ناهاوسەنگ</string>
+ <string name="renderer_asynchronous_shaders_description">سێبەرەکان بە شێوەیەکی ناهاوسەنگ کۆدەکاتەوە، پچڕپچڕی کەمدەکاتەوە بەڵام لەوانەیە گلێچ دروستکا.</string>
+ <string name="renderer_reactive_flushing">بەکارهێنانی بەرپێچدەرەوە</string>
+ <string name="renderer_reactive_flushing_description">وردی ڕێندەرکردن لە هەندێک یاریدا باشتر دەکات لەسەر تێچووی کارایی.</string>
+ <string name="use_disk_shader_cache">بیرگەخێرای سێبەری دیسک</string>
+ <string name="use_disk_shader_cache_description">پچڕپچڕی کەمدەکاتەوە بە هەڵگرتن و بارکردنی سێبەری دروستکراو لە ناوخۆدا.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="renderer_api">API گرافیک</string>
+ <string name="renderer_debug">چاککردنەوەی گرافیک</string>
+ <string name="renderer_debug_description">API ی گرافیکەکان ڕێکدەخات بۆ دۆخی چاککردنی خاو.</string>
+ <string name="audio_volume">قەبارەی دەنگی</string>
+ <string name="audio_volume_description">دیاریکردنی قەبارەی دەنگی دەرچووی بیستۆک و بزوێنەری دەنگی دەرەکی.</string>
+
+ <!-- Miscellaneous -->
+ <string name="slider_default">بنەڕەت</string>
+ <string name="ini_saved">ڕێکخستنە پاشەکەوتکراوەکان</string>
+ <string name="gameid_saved">ڕێکخستنە پاشەکەوتکراوەکان بۆ %1$s</string>
+ <string name="error_saving">هەڵە لە پاشەکەوتکردن %1$s.ini: %2$s</string>
+ <string name="loading">بارکردن...</string>
+ <string name="reset_setting_confirmation">ئایا دەتەوێت ئەم ڕێکخستنە بگەڕێنیتەوە بۆ بەهای بنەڕەتی خۆی؟</string>
+ <string name="reset_to_default">دوبارە ڕێکخستنەوەی بۆ بنەڕەت</string>
+ <string name="reset_all_settings">هەموو ڕێکخستنەکان دوبارە ڕێک دەخاتەوە؟</string>
+ <string name="reset_all_settings_description">هەموو ڕێکخستنە پێشکەوتووەکان دەگەڕێنەوە بۆ ڕێکخستنی بنەڕەتی خۆیان. پاشگەز بوونەوەی نییه.</string>
+ <string name="settings_reset">دوبارە ڕێککردنەوەی ڕێکخستنەکان</string>
+ <string name="close">داخستن</string>
+ <string name="learn_more">زیاتر فێربە</string>
+ <string name="auto">خودکار</string>
+ <string name="submit">پێشکەشکردن</string>
+ <string name="string_import">هاوردەکردن</string>
+ <string name="export">هەناردەکردن</string>
+ <!-- GPU driver installation -->
+ <string name="select_gpu_driver">هەڵبژاردنی وەگەڕخەری GPU</string>
+ <string name="select_gpu_driver_title">حەز دەکەیت وەگەڕخەری GPU ی ئێستات بگۆڕیت؟</string>
+ <string name="select_gpu_driver_install">دامەزراندن</string>
+ <string name="select_gpu_driver_default">بنەڕەت</string>
+ <string name="select_gpu_driver_use_default">بەکارهێنانی وەگەڕخەری GPU ی بنەڕەت</string>
+ <string name="select_gpu_driver_error">وەگەڕخەری نادروست هەڵبژێردرا، بە بەکارهێنانی بنەڕەتی سیستەم!</string>
+ <string name="system_gpu_driver">وەگەڕخەری GPU ی سیستەم</string>
+ <string name="installing_driver">دامەزراندنی وەگەڕخەر...</string>
+
+ <!-- Preferences Screen -->
+ <string name="preferences_settings">ڕێکخستنەکان</string>
+ <string name="preferences_general">گشتی</string>
+ <string name="preferences_system">سیستەم</string>
+ <string name="preferences_graphics">گرافیک</string>
+ <string name="preferences_audio">دەنگ</string>
+ <string name="preferences_theme">ڕەنگ و ڕووکار</string>
+ <string name="preferences_debug">چاککردنەوە</string>
+
+ <!-- ROM loading errors -->
+ <string name="loader_error_encrypted">ڕۆمەکەت کۆدکراوە</string>
+ <string name="loader_error_encrypted_keys_description"><![CDATA[تکایە دڵنیابەوە لەدامەزراوی <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> فایلەکەت بۆ ئەوەی بتوانرێت یارییەکان کۆد بکرێنەوە.]]></string>
+ <string name="loader_error_video_core">هەڵەیەک لە دەستپێکردنی ناوەکی ڤیدیۆکەدا ڕوویدا</string>
+ <string name="loader_error_video_core_description">ئەمەش بەزۆری بەهۆی وەگەڕخەرێکی ناتەبای GPU ەوەیە. دامەزراندنی وەگەڕخەری GPU ی تایبەتمەندکراو لەوانەیە ئەم کێشەیە چارەسەر بکات.</string>
+ <string name="loader_error_invalid_format">ناتوانرێت ڕۆم باربکرێت</string>
+ <string name="loader_error_file_not_found">فایلی ڕۆم بوونی نییە</string>
+
+ <!-- Emulation Menu -->
+ <string name="emulation_exit">دەرچوون لە ئیمولەیشن</string>
+ <string name="emulation_done">تەواو</string>
+ <string name="emulation_fps_counter">FPS ژمێر</string>
+ <string name="emulation_toggle_controls">گۆڕینی کۆنتڕۆڵ</string>
+ <string name="emulation_rel_stick_center">ناوەندی گێڕ بەنزیکەیی</string>
+ <string name="emulation_dpad_slide">خلیسکانی 4 دوگمەکە</string>
+ <string name="emulation_haptics">لەرینەوەی پەنجەلێدان</string>
+ <string name="emulation_show_overlay">نیشاندانی داپۆشەر</string>
+ <string name="emulation_toggle_all">گۆڕینی سەرجەم</string>
+ <string name="emulation_control_adjust">ڕێکخستنی داپۆشەر</string>
+ <string name="emulation_control_scale">پێوەر</string>
+ <string name="emulation_control_opacity">ڕوونی</string>
+ <string name="emulation_touch_overlay_reset">دووبارە ڕێکخستنەوەی داپۆشەر</string>
+ <string name="emulation_touch_overlay_edit">دەستکاریکردنی داپۆشەر</string>
+ <string name="emulation_pause">وەستاندنی ئیمولەیشن</string>
+ <string name="emulation_unpause">لادانی وەستاندنی ئیمولەیشن</string>
+ <string name="emulation_input_overlay">هەڵبژاردەکانی داپۆشەر</string>
+
+ <string name="load_settings">بارکردنی ڕێکخستنەکان...</string>
+
+ <!-- Software keyboard -->
+ <string name="software_keyboard">کیبۆردی نەرمەکاڵا</string>
+
+ <!-- Errors and warnings -->
+ <string name="abort_button">دەربارە</string>
+ <string name="continue_button">بەردەوام بوون</string>
+ <string name="system_archive_not_found">ئەرشیفی سیستەم نەدۆزراوە</string>
+ <string name="system_archive_not_found_message">%s دیار نییە. تکایە ئەرشیفی سیستەمەکەت فڕێ بدە.\nبەردەوامی ئیمولەیشن لەوانەیە ببێتە هۆی تێکچوون و فڕێدانەدەرەوە.</string>
+ <string name="system_archive_general">ئەرشیفێکی سیستەم</string>
+ <string name="save_load_error">هەڵەی پاشەکەوتکردن/بارکردن</string>
+ <string name="fatal_error">هەڵەی کوشندە</string>
+ <string name="fatal_error_message">هەڵەیەکی کوشندە ڕوویدا. بۆ وردەکارییەکان لۆگەکە بپشکنە.\nبەردەوامی ئیمولەیشن لەوانەیە ببێتە هۆی تێکچوون و فڕێدانەدەرەوە.</string>
+ <string name="performance_warning">کوژاندنەوەی ئەم ڕێکخستنە دەبێتە هۆی کەمکردنەوەی کارایی ئیمولەیشن! بۆ باشترین ئەزموون، باشترە ئەم ڕێکخستنە چالاک بهێڵیتەوە.</string>
+ <!-- Region Names -->
+ <string name="region_japan">ژاپۆن</string>
+ <string name="region_usa">ئەمریکا</string>
+ <string name="region_europe">ئەورووپا</string>
+ <string name="region_australia">ئوسترالیا</string>
+ <string name="region_china">چین</string>
+ <string name="region_korea">کۆریا</string>
+ <string name="region_taiwan">تایوان</string>
+
+ <string name="memory_gigabyte">GB</string>
+ <!-- Renderer APIs -->
+ <string name="renderer_vulkan">ڤوڵکان</string>
+ <string name="renderer_none">هیچ</string>
+
+ <!-- Renderer Accuracy -->
+ <string name="renderer_accuracy_normal">ئاسایی</string>
+ <string name="renderer_accuracy_high">بەرز</string>
+ <string name="renderer_accuracy_extreme">ئەوپەڕ (خاو)</string>
+
+ <!-- Resolutions -->
+ <string name="resolution_half">0.5X (360p/540p)</string>
+ <string name="resolution_three_quarter">0.75X (540p/810p)</string>
+ <string name="resolution_one">1X (720p/1080p)</string>
+ <string name="resolution_two">2X (1440p/2160p) (خاو)</string>
+ <string name="resolution_three">3X (2160p/3240p) (خاو)</string>
+ <string name="resolution_four">4X (2880p/4320p) (خاو)</string>
+
+ <!-- Renderer VSync -->
+ <string name="renderer_vsync_immediate">دەستبەجێ (کوژاوە)</string>
+ <string name="renderer_vsync_mailbox">سندوقی پۆستە</string>
+ <string name="renderer_vsync_fifo">FIFO (پێکراو)</string>
+ <string name="renderer_vsync_fifo_relaxed">FIFO ئارام</string>
+
+ <!-- Scaling Filters -->
+ <string name="scaling_filter_nearest_neighbor">نزیکترین دراوسێ</string>
+ <string name="scaling_filter_bilinear">دوو هێڵی</string>
+ <string name="scaling_filter_bicubic">دووخشتەکی</string>
+ <string name="scaling_filter_gaussian">گاوسی</string>
+ <string name="scaling_filter_scale_force">پێوەرهێز</string>
+ <string name="scaling_filter_fsr">AMD FidelityFX™ سوپەر ووردبینی</string>
+
+ <!-- Anti-Aliasing -->
+ <string name="anti_aliasing_none">هیچ</string>
+ <string name="anti_aliasing_fxaa">FXAA</string>
+ <string name="anti_aliasing_smaa">SMAA</string>
+
+ <string name="screen_layout_auto">خودکار</string>
+
+ <!-- Aspect Ratios -->
+ <string name="ratio_default">بنەڕەت (16:9)</string>
+ <string name="ratio_force_four_three">ڕووبەری 4:3</string>
+ <string name="ratio_force_twenty_one_nine">ڕووبەری 21:9</string>
+ <string name="ratio_force_sixteen_ten">ڕووبەری 16:10</string>
+ <string name="ratio_stretch">کشانی پڕ بەشاشە</string>
+
+ <!-- CPU Accuracy -->
+ <string name="cpu_accuracy_accurate">وورد</string>
+ <string name="cpu_accuracy_unsafe">ناسەقامگیر</string>
+ <string name="cpu_accuracy_paranoid">بەگومان (خاو)</string>
+
+ <!-- Gamepad Buttons -->
+ <string name="gamepad_d_pad">4 دوگمەکە</string>
+ <string name="gamepad_left_stick">گێڕی چەپ</string>
+ <string name="gamepad_right_stick">گێڕی ڕاست</string>
+ <string name="gamepad_home">ماڵەوە</string>
+ <string name="gamepad_screenshot">وێنەگرتنی شاشە</string>
+
+ <!-- Disk shader cache -->
+ <string name="preparing_shaders">ئامادەکردنی سێبەرەکان</string>
+ <string name="building_shaders">دروستکردنی سێبەرەکان</string>
+
+ <!-- Theme options -->
+ <string name="change_app_theme">گۆڕینی ڕووکاری ئەپەکە</string>
+ <string name="theme_default">بنەڕەت</string>
+ <string name="theme_material_you">کەرەستەی تۆ</string>
+
+ <!-- Theme Modes -->
+ <string name="change_theme_mode">گۆڕینی دۆخی ڕووکار</string>
+ <string name="theme_mode_follow_system">پەیڕەوی کردنی سیستەم</string>
+ <string name="theme_mode_light">ڕوناکی</string>
+ <string name="theme_mode_dark">تاریک</string>
+
+ <!-- Black backgrounds theme -->
+ <string name="use_black_backgrounds">پاشبنەمای ڕەش</string>
+ <string name="use_black_backgrounds_description">لە کاتی بەکارهێنانی ڕووکاری تاریکدا، پاشبنەمای ڕەش دادەنێ.</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">مۆڵەتەکان</string>
+ <string name="license_fidelityfx_fsr_description">بەرزکردنەوەی کوالێتی بەرز لە کۆمپانیای AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml
index 72a47fbdb..9c6590b5e 100644
--- a/src/android/app/src/main/res/values-de/strings.xml
+++ b/src/android/app/src/main/res/values-de/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">Diese Software kann Spiele für die Nintendo Switch abspielen. Keine Spiele oder Spielekeys sind enthalten.&lt;br /&gt;&lt;br /&gt;Bevor du beginnst, bitte halte deine <![CDATA[<b> prod.keys </b>]]> auf deinem Gerät bereit. .&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Mehr Infos</a>]]></string>
<string name="emulation_notification_channel_name">Emulation ist aktiv</string>
@@ -25,6 +25,7 @@
<string name="back">Zurück</string>
<string name="add_games">Spiele hinzufügen</string>
<string name="add_games_description">Spieleverzeichnis auswählen</string>
+ <string name="step_complete">Fertig!</string>
<!-- Home strings -->
<string name="home_games">Spiele</string>
@@ -38,6 +39,7 @@
<string name="add_games_warning_description">Spiele werden in der Spieleliste nicht angezeigt, wenn kein Ordner ausgewählt ist.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">Spiele suchen</string>
+ <string name="search_settings">Einstellungen suchen</string>
<string name="games_dir_selected">Spieleverzeichnis ausgewählt</string>
<string name="install_prod_keys">prod.keys installieren</string>
<string name="install_prod_keys_description">Zum Entschlüsseln von Spielen benötigt</string>
@@ -60,8 +62,11 @@
<string name="invalid_keys_file">Ungültige Schlüsseldatei ausgewählt</string>
<string name="install_keys_success">Schlüssel erfolgreich installiert</string>
<string name="reading_keys_failure">Fehler beim Lesen der Schlüssel</string>
+ <string name="install_prod_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".keys\" hat, und versuchen Sie es erneut.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".bin\" hat, und versuchen Sie es erneut.</string>
<string name="invalid_keys_error">Ungültige Schlüssel</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
+ <string name="install_keys_failure_description">Die ausgewählte Datei ist falsch oder beschädigt. Bitte kopieren Sie Ihre Schlüssel erneut.</string>
<string name="install_gpu_driver">GPU-Treiber installieren</string>
<string name="install_gpu_driver_description">Alternative Treiber für eventuell bessere Leistung oder Genauigkeit installieren</string>
<string name="advanced_settings">Erweiterte Einstellungen</string>
@@ -84,7 +89,17 @@
<string name="save_file_invalid_zip_structure_description">Der erste Unterordnername muss die Titel-ID des Spiels sein.</string>
<string name="import_saves">Importieren</string>
<string name="export_saves">Exportieren</string>
-
+ <string name="install_firmware">Firmware installieren</string>
+ <string name="install_firmware_description">Die Firmware muss in einem ZIP-Archiv vorliegen und wird zum Booten einiger Spiele benötigt</string>
+ <string name="firmware_installing">Firmware wird installiert</string>
+ <string name="firmware_installed_success">Die Firmware wurde erfolgreich installiert!</string>
+ <string name="firmware_installed_failure">Bei der Firmware installation ist etwas fehlgeschlagen.</string>
+ <string name="share_log">Debug-Logs teilen</string>
+ <string name="share_log_description">Debug-Logs an yuzu zur Untersuchung absenden</string>
+ <string name="share_log_missing">Keine Log-Datei gefunden</string>
+ <string name="install_game_content">Spiel installieren</string>
+ <string name="install_game_content_description">Spiel Update oder DLC installieren</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia ist nicht real</string>
<string name="copied_to_clipboard">In die Zwischenablage kopiert</string>
@@ -92,7 +107,10 @@
<string name="contributors">Beitragende</string>
<string name="contributors_description">Gemacht mit \u2764 vom yuzu Team</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Projekte, die yuzu für Android möglich machen </string>
<string name="build">Build</string>
+ <string name="user_data">Nutzerdaten</string>
+ <string name="user_data_export_cancelled">Export abgebrochen</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -107,45 +125,39 @@
<string name="early_access_updates">Früherer Zugriff auf Updates</string>
<string name="no_manual_installation">Keine manuelle Installation</string>
<string name="prioritized_support">Priorisierte Unterstützung</string>
+ <string name="helping_game_preservation">Beitrag zur Erhaltung der Spiele</string>
<string name="our_eternal_gratitude">Unsere ewige Dankbarkeit</string>
<string name="are_you_interested">Bist du interessiert?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Geschwindigkeitsbegrenzung aktivieren</string>
- <string name="frame_limit_enable_description">Wenn aktiviert, wird die Emulationsgeschwindigkeit auf einen Prozentsatz der normalen Geschwindigkeit begrenzt.</string>
+ <string name="frame_limit_enable">Limitierte Geschwindigkeit</string>
+ <string name="frame_limit_enable_description">Limitiert die Geschwindigkeit auf einen von dir festgelegten Prozentsatz.</string>
<string name="frame_limit_slider">Geschwindkeitsbegrenzung in Prozent</string>
- <string name="frame_limit_slider_description">Legt den Prozentsatz der Bergrenzung der Emulationsgeschwindigkeit fest. Mit dem Standardwert von 100% wird die Emulation auf die normale Geschwindigkeit begrenzt. Höhere oder niedrigere Werte erhöhen oder verringern die Geschwindigkeitsbegrenzung.</string>
+ <string name="frame_limit_slider_description">Gibt die prozentuale Geschwindigkeit der Emulation an. 100% sind normal. Werte darüber oder drunter werden die Geschwindigkeit entsprechend verändern.</string>
<string name="cpu_accuracy">CPU-Genauigkeit</string>
-
<!-- System settings strings -->
- <string name="use_docked_mode">Dock-Modus</string>
- <string name="use_docked_mode_description">Emuliert im Dock-Modus, was die Auflösung verbessert, aber die Leistung senkt.</string>
+ <string name="use_docked_mode">Gedockter Modus</string>
+ <string name="use_docked_mode_description">Der Docked Modus erhöht die Auflösung, verringert die aber die Leistung. Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die Leistung.</string>
<string name="emulated_region">Emulierte Region</string>
<string name="emulated_language">Emulierte Sprache</string>
<string name="select_rtc_date">RTC-Datum auswählen</string>
<string name="select_rtc_time">RTC-Zeit auswählen</string>
- <string name="use_custom_rtc">Benutzerdefinierte RTC aktivieren</string>
- <string name="use_custom_rtc_description">Mit dieser Einstellung kann eine benutzerdefinierte Echtzeituhr unabhängig von der aktuellen Systemzeit verwendet werden.</string>
- <string name="set_custom_rtc">Benutzerdefinierte RTC einstellen</string>
-
+ <string name="use_custom_rtc">Benutzerdefinierte Echtzeituhr</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Genauigkeitsstufe</string>
- <string name="renderer_resolution">Auflösung</string>
<string name="renderer_vsync">VSync-Modus</string>
+ <string name="renderer_screen_layout">Orientierung</string>
<string name="renderer_aspect_ratio">Seitenverhältnis</string>
<string name="renderer_scaling_filter">Fensteranpassungsfilter</string>
- <string name="renderer_anti_aliasing">Kantenglättungs-Methode</string>
<string name="renderer_force_max_clock">Maximale Taktfrequenz erzwingen (nur Adreno)</string>
<string name="renderer_force_max_clock_description">Erzwingt den Betrieb der GPU mit der maximal möglichen Taktfrequenz (Temperaturbeschränkungen werden weiterhin angewendet).</string>
<string name="renderer_asynchronous_shaders">Asynchrone Shader nutzen</string>
- <string name="renderer_asynchronous_shaders_description">Kompiliert Shader asynchron, was Ruckler reduziert, aber zu Glitches führen kann.</string>
- <string name="renderer_debug">Grafik-Debugging aktivieren</string>
- <string name="renderer_debug_description">Wenn aktiviert, schaltet die Grafik-API in einen langsameren Debugging-Modus.</string>
- <string name="use_disk_shader_cache">Nutze Festplatten-Shader-Cache</string>
- <string name="use_disk_shader_cache_description">Ruckeln wird durch das Speichern und Laden von generierten Shadern auf der Festplatte reduziert.</string>
-
- <!-- Audio settings strings -->
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">CPU Debugging</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Graphik-Debugging</string>
<string name="audio_volume">Lautstärke</string>
<string name="audio_volume_description">Legt die Lautstärke der Audioausgabe fest.</string>
@@ -154,14 +166,22 @@
<string name="ini_saved">Einstellungen gespeichert</string>
<string name="gameid_saved">Einstellungen für %1$s gespeichert</string>
<string name="error_saving">Fehler beim Speichern von %1$s.ini: %2$s</string>
+ <string name="unimplemented_menu">Unimplementiertes Menü</string>
<string name="loading">Lädt...</string>
<string name="reset_setting_confirmation">Möchtest du diese Einstellung auf den Standardwert zurücksetzen?</string>
<string name="reset_to_default">Auf Standard zurücksetzen</string>
<string name="reset_all_settings">Alle Einstellungen zurücksetzen?</string>
- <string name="reset_all_settings_description">Alle erweiterten Einstellungen werden auf ihren Standardwert zurückgesetzt. Dies kann nicht rückgängig gemacht werden.</string>
<string name="settings_reset">Einstellungen zurückgesetzt</string>
<string name="close">Schließen</string>
<string name="learn_more">Mehr erfahren</string>
+ <string name="auto">Auto</string>
+ <string name="submit">Absenden</string>
+ <string name="string_null">Null</string>
+ <string name="string_import">Importieren</string>
+ <string name="export">Exportieren</string>
+ <string name="export_failed">Export fehlgeschlagen</string>
+ <string name="import_failed">Import fehlgeschlagen</string>
+ <string name="cancelling">Abbrechen</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">GPU-Treiber auswählen</string>
@@ -169,6 +189,7 @@
<string name="select_gpu_driver_install">Installieren</string>
<string name="select_gpu_driver_default">Standard</string>
<string name="select_gpu_driver_use_default">Standard GPU-Treiber wird verwendet</string>
+ <string name="select_gpu_driver_error">Ungültiger Treiber ausgewählt, Standard-Treiber wird verwendet!</string>
<string name="system_gpu_driver">System GPU-Treiber</string>
<string name="installing_driver">Treiber wird installiert...</string>
@@ -179,6 +200,7 @@
<string name="preferences_graphics">Grafik</string>
<string name="preferences_audio">Audio</string>
<string name="preferences_theme">Theme und Farbe</string>
+ <string name="preferences_debug">Debug</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Das ROM ist verschlüsselt</string>
@@ -192,22 +214,15 @@
<string name="emulation_exit">Emulation beenden</string>
<string name="emulation_done">Fertig</string>
<string name="emulation_fps_counter">FPS Zähler</string>
- <string name="emulation_toggle_controls">Steuerung umschalten</string>
- <string name="emulation_rel_stick_center">Relative Stick-Mitte</string>
- <string name="emulation_dpad_slide">DPad Slide</string>
- <string name="emulation_haptics">Haptik</string>
- <string name="emulation_show_overlay">Overlay anzeigen</string>
<string name="emulation_toggle_all">Alle umschalten</string>
<string name="emulation_control_adjust">Overlay anpassen</string>
<string name="emulation_control_scale">Größe</string>
<string name="emulation_control_opacity">Transparenz</string>
<string name="emulation_touch_overlay_reset">Overlay zurücksetzen</string>
<string name="emulation_touch_overlay_edit">Overlay bearbeiten</string>
- <string name="emulation_pause">Emulation pausieren</string>
- <string name="emulation_unpause">Emulation fortsetzen</string>
<string name="emulation_input_overlay">Overlay-Optionen</string>
- <string name="load_settings">Lädt Einstellungen...</string>
+ <string name="load_settings">Lade Einstellungen...</string>
<!-- Software keyboard -->
<string name="software_keyboard">Software-Tastatur</string>
@@ -221,7 +236,7 @@
<string name="fatal_error">Schwerwiegender Fehler</string>
<string name="fatal_error_message">Ein schwerwiegender Fehler ist aufgetreten. Einzelheiten wurden im Log protokolliert.\nDas Fortsetzen der Emulation kann zu Abstürzen und Bugs führen.</string>
<string name="performance_warning">Das Deaktivieren dieser Einstellung führt zu erheblichen Leistungsverlusten! Für ein optimales Erlebnis wird empfohlen, sie aktiviert zu lassen.</string>
-
+ <string name="memory_formatted">%1$s %2$s</string>
<!-- Region Names -->
<string name="region_japan">Japan</string>
<string name="region_usa">USA</string>
@@ -231,6 +246,15 @@
<string name="region_korea">Korea</string>
<string name="region_taiwan">Taiwan</string>
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
+
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
<string name="renderer_none">Keiner</string>
@@ -267,12 +291,15 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <string name="screen_layout_portrait">Portrait</string>
+ <string name="screen_layout_auto">Auto</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Standard (16:9)</string>
<string name="ratio_force_four_three">4:3 erzwingen</string>
<string name="ratio_force_twenty_one_nine">21:9 erzwingen</string>
<string name="ratio_force_sixteen_ten">Erzwinge 16:10</string>
- <string name="ratio_stretch">Auf Fenster anpassen</string>
+ <string name="ratio_stretch">Auf Bildschirmgröße anpsassen</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">Akkurat</string>
@@ -280,9 +307,9 @@
<string name="cpu_accuracy_paranoid">Paranoid (Langsam)</string>
<!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">Steuerkreuz</string>
- <string name="gamepad_left_stick">Linker Analogstick</string>
- <string name="gamepad_right_stick">Rechter Analogstick</string>
+ <string name="gamepad_d_pad">D-Pad</string>
+ <string name="gamepad_left_stick">Linker Stick</string>
+ <string name="gamepad_right_stick">Rechter Stick</string>
<string name="gamepad_home">Home</string>
<string name="gamepad_screenshot">Screenshot</string>
@@ -291,18 +318,30 @@
<string name="building_shaders">Shader werden erstellt</string>
<!-- Theme options -->
- <string name="change_app_theme">App-Theme ändern</string>
+ <string name="change_app_theme">App-Thema ändern</string>
<string name="theme_default">Standard</string>
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
- <string name="change_theme_mode">Theme-Modus ändern</string>
+ <string name="change_theme_mode">Themen-Modus ändern</string>
<string name="theme_mode_follow_system">System folgen</string>
<string name="theme_mode_light">Hell</string>
<string name="theme_mode_dark">Dunkel</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Schwarze Hintergünde verwenden</string>
+ <string name="use_black_backgrounds">Schwarze Hintergründe</string>
<string name="use_black_backgrounds_description">Bei Verwendung des dunklen Themes, schwarze Hintergründe verwenden.</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Bild im Bild</string>
+ <string name="pause">Pause</string>
+ <string name="mute">Stummschalten</string>
+ <string name="unmute">Ton aktivieren</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Lizenzen</string>
+ <string name="license_fidelityfx_fsr_description">Hochwertiges Upscaling von AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml
index e5bdd5889..103ac6e65 100644
--- a/src/android/app/src/main/res/values-es/strings.xml
+++ b/src/android/app/src/main/res/values-es/strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
- <string name="app_disclaimer">Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o keys no vienen incluidos.&lt;br /&gt;&lt;br /&gt;Antes de empezar, por favor, localice el archivo <![CDATA[<b> prod.keys </b>]]>en el almacenamiento de su dispositivo..&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Saber más</a>]]></string>
+ <string name="app_disclaimer">Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o claves no vienen incluidos.&lt;br /&gt;&lt;br /&gt;Antes de empezar, por favor, localice el archivo <![CDATA[<b> prod.keys </b>]]>en el almacenamiento de su dispositivo..&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Saber más</a>]]></string>
<string name="emulation_notification_channel_name">Emulación activa</string>
<string name="emulation_notification_channel_description">Muestra una notificación persistente cuando la emulación está activa.</string>
<string name="emulation_notification_running">yuzu esta ejecutándose</string>
@@ -25,6 +25,7 @@
<string name="back">Atrás</string>
<string name="add_games">Añadir Juegos</string>
<string name="add_games_description">Selecciona la carpeta de juegos</string>
+ <string name="step_complete">¡Completado!</string>
<!-- Home strings -->
<string name="home_games">Juegos</string>
@@ -37,7 +38,8 @@
<string name="add_games_warning">¿Omitir la selección de la carpeta de juegos?</string>
<string name="add_games_warning_description">No se mostrará ningún juego si no se ha seleccionado una carpeta de juegos.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
- <string name="home_search_games">Buscar Juegos</string>
+ <string name="home_search_games">Buscar juegos</string>
+ <string name="search_settings">Buscar configuración</string>
<string name="games_dir_selected">Directorio de juegos seleccionado</string>
<string name="install_prod_keys">Instalar prod.keys</string>
<string name="install_prod_keys_description">Requerido para descifrar juegos</string>
@@ -58,15 +60,18 @@
<string name="warning_cancel">Cancelar</string>
<string name="install_amiibo_keys">Instalar clave de Amiiboo</string>
<string name="install_amiibo_keys_description">Necesario para usar Amiibo en el juego</string>
- <string name="invalid_keys_file">Archivo de claves inválido seleccionado</string>
+ <string name="invalid_keys_file">Archivo de claves seleccionado inválido</string>
<string name="install_keys_success">Claves instaladas correctamente</string>
<string name="reading_keys_failure">Error al leer las claves de cifrado</string>
+ <string name="install_prod_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .keys y pruebe otra vez.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .bin y pruebe otra vez.</string>
<string name="invalid_keys_error">Claves de cifrado no válidas</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.</string>
<string name="install_gpu_driver">Instalar driver de GPU</string>
<string name="install_gpu_driver_description">Instale drivers alternativos para obtener un rendimiento o una precisión potencialmente mejores</string>
<string name="advanced_settings">Opciones avanzadas</string>
+ <string name="advanced_settings_game">Configuración avanzada: %1$s</string>
<string name="settings_description">Configurar las opciones del emulador</string>
<string name="search_recently_played">Jugado recientemente</string>
<string name="search_recently_added">Añadido recientemente</string>
@@ -86,6 +91,33 @@
<string name="save_file_invalid_zip_structure_description">El nombre de la primera subcarpeta debe ser el Title ID del juego.</string>
<string name="import_saves">Importar</string>
<string name="export_saves">Exportar</string>
+ <string name="install_firmware">Instalar firmware</string>
+ <string name="install_firmware_description">El firmware debe estar en un archivo ZIP y es necesario para ejecutar algunos juegos</string>
+ <string name="firmware_installing">Instalando firmware</string>
+ <string name="firmware_installed_success">Firmware instalado con éxito</string>
+ <string name="firmware_installed_failure">Falló la instalación de firmware</string>
+ <string name="firmware_installed_failure_description">Asegúrese de que los archivos nca del firmware estén en la raíz del zip e inténtelo de nuevo.</string>
+ <string name="share_log">Compartir registros de depuración</string>
+ <string name="share_log_description">Comparta el archivo de registro de yuzu para depurar problemas</string>
+ <string name="share_log_missing">No se encontró ningún archivo de registro</string>
+ <string name="install_game_content">Instalar contenido de juego</string>
+ <string name="install_game_content_description">Instalar actualizaciones o DLC</string>
+ <string name="installing_game_content">Instalando contenido...</string>
+ <string name="install_game_content_failure">Error instalando archivo(s) a la NAND</string>
+ <string name="install_game_content_failure_description">Asegúrese de que el/los contenido(s) son válidos y que el archivo prod.keys esté instalado.</string>
+ <string name="install_game_content_failure_base">La instalación de los juegos base no está permitida para así evitar posibles conflictos.</string>
+ <string name="install_game_content_failure_file_extension">Sólo hay soporte para el contenido en NSP y XCI. Asegúrese de que el/los contenido(s) son válidos.</string>
+ <string name="install_game_content_failed_count">%1$d error(es) de instalación</string>
+ <string name="install_game_content_success">Contenido(s) de juego instalado/s con éxito</string>
+ <string name="install_game_content_success_install">%1$d instalado con éxito</string>
+ <string name="install_game_content_success_overwrite">%1$d sobreescrito con éxito</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">Drivers personalizados no soportados</string>
+ <string name="custom_driver_not_supported_description">En estos momentos, la carga de drivers personalizados no está disponible para este dispositivo..\n¡Comprueba esta opción en el futuro para ver si ya está añadido el soporte a ese dispositivo!</string>
+ <string name="manage_yuzu_data">Administrar datos de yuzu</string>
+ <string name="manage_yuzu_data_description">Importa/exporta el firmware, las keys, los datos de usuario, ¡y más!</string>
+ <string name="share_save_file">Compartir archivo de guardado</string>
+ <string name="export_save_failed">La exportación del guardado falló</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia no es real</string>
@@ -94,7 +126,18 @@
<string name="contributors">Contribuidores</string>
<string name="contributors_description">Hecho con \u2764 del equipo yuzu</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Proyectos que hacen que yuzu para Android sea una realidad</string>
<string name="build">Versión</string>
+ <string name="user_data">Datos de usuario</string>
+ <string name="user_data_description">Importa/exporta todos los datos de usuario.\n\nCuando se importen los datos de usuario, ¡los demás datos de usuario existentes serán borrados!</string>
+ <string name="exporting_user_data">Exportando datos de usuario...</string>
+ <string name="importing_user_data">Importando datos de usuario...</string>
+ <string name="import_user_data">Importar datos de usuario</string>
+ <string name="invalid_yuzu_backup">Backup de válido</string>
+ <string name="user_data_export_success">Datos de usuario exportados con éxito</string>
+ <string name="user_data_import_success">Datos de usuario importados con éxito</string>
+ <string name="user_data_export_cancelled">Exportación cancelada</string>
+ <string name="user_data_import_failed_description">Asegúrese de que las carpetas de datos de usuario estén en la raíz de la carpeta del zip y contengan un archivo config en config/config.ini e inténtelo de nuevo.</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
<string name="are_you_interested">¿Estás interesado?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Activar limite de velocidad</string>
- <string name="frame_limit_enable_description">Cuando está habilitado, la velocidad de emulación se limitará a un porcentaje específico de la velocidad normal.</string>
+ <string name="frame_limit_enable">Limitar velocidad</string>
+ <string name="frame_limit_enable_description">Limita la velocidad de emulación a un porcentaje específico de la velocidad normal.</string>
<string name="frame_limit_slider">Limitar porcentaje de velocidad</string>
- <string name="frame_limit_slider_description">Especifica el porcentaje para limitar la velocidad de emulación. Con el valor predeterminado del 100 %, la emulación se limitará a la velocidad normal. Valores más altos o más bajos aumentarán o disminuirán el límite de velocidad.</string>
+ <string name="frame_limit_slider_description">Especifica el porcentaje para limitar la velocidad de emulación. 100% es la velocidad normal. Valores más altos o bajos incrementarán o disminuirán el límite de velocidad.</string>
<string name="cpu_accuracy">Precisión de CPU</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
- <string name="use_docked_mode">Modo sobremesa</string>
- <string name="use_docked_mode_description">Emula en modo sobremesa, lo que aumenta la resolución perjudicando el rendimiento.</string>
+ <string name="use_docked_mode">Modo Sobremesa</string>
+ <string name="use_docked_mode_description">Incrementa la resolución al coste de reducir el rendimiento. El Modo Portátil es usado cuando está desactivado, reduciendo la resolución y mejorando así el rendimiento.</string>
<string name="emulated_region">Región emulada</string>
<string name="emulated_language">Idioma emulado</string>
- <string name="select_rtc_date">Seleccionar Fecha RTC</string>
- <string name="select_rtc_time">Seleccionar Tiempo RTC</string>
- <string name="use_custom_rtc">Habilitar RTC Personalizado</string>
- <string name="use_custom_rtc_description">Esta configuración le permite configurar un reloj de tiempo real personalizado diferente a la hora actual de su sistema</string>
- <string name="set_custom_rtc">Establecer RTC Personalizado</string>
+ <string name="select_rtc_date">Seleccionar fecha RTC</string>
+ <string name="select_rtc_time">Seleccionar tiempo RTC</string>
+ <string name="use_custom_rtc">RTC personalizado</string>
+ <string name="use_custom_rtc_description">Te permite tener un reloj personalizado en tiempo real diferente del tiempo del propio sistema.</string>
+ <string name="set_custom_rtc">Configurar RTC personalizado</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Nivel de precisión</string>
- <string name="renderer_resolution">Resolución</string>
+ <string name="renderer_resolution">Resolución (Portátil/Sobremesa)</string>
<string name="renderer_vsync">Modo VSync</string>
+ <string name="renderer_screen_layout">Orientación</string>
<string name="renderer_aspect_ratio">Relación de aspecto</string>
<string name="renderer_scaling_filter">Filtro de adaptación de ventana</string>
- <string name="renderer_anti_aliasing">Metodo Anti Aliasing</string>
+ <string name="renderer_anti_aliasing">Método anti-aliasing</string>
<string name="renderer_force_max_clock">Forzar velocidad al máximo (solo Adreno)</string>
<string name="renderer_force_max_clock_description">Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas).</string>
<string name="renderer_asynchronous_shaders">Usar shaders asíncronos</string>
- <string name="renderer_asynchronous_shaders_description">Compila shaders de forma asincrónica, lo que reducirá los parones pero puede introducir fallos.</string>
- <string name="renderer_debug">Habilitar la depuración de gráficos</string>
- <string name="renderer_debug_description">Cuando esté marcado, la API de gráficos entra en un modo de depuración más lento.</string>
- <string name="use_disk_shader_cache">Usar caché de shaders en disco</string>
- <string name="use_disk_shader_cache_description">Reduzca los parones almacenando y cargando shaders generados en el disco.</string>
+ <string name="renderer_asynchronous_shaders_description">Compila shaders de manera asíncrona, reduciendo los parones, pero puede introducir fallos.</string>
+ <string name="renderer_reactive_flushing">Usar limpieza reactiva</string>
+ <string name="renderer_reactive_flushing_description">Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento.</string>
+ <string name="use_disk_shader_cache">Caché de shaders en disco</string>
+ <string name="use_disk_shader_cache_description">Reduce los parones almacenando y cargando shaders generados.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">Depuración de CPU</string>
+ <string name="cpu_debug_mode_description">Pone la CPU en un modo de depuración lento.</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Depuración de gráficos</string>
+ <string name="renderer_debug_description">Configura la API gráfica a un modo de depuración lento.</string>
+ <string name="fastmem">Fastmem</string>
<!-- Audio settings strings -->
+ <string name="audio_output_engine">Motor de salida</string>
<string name="audio_volume">Volumen</string>
<string name="audio_volume_description">Especifica el volumen de la salida de audio.</string>
@@ -157,14 +212,24 @@
<string name="ini_saved">Configuración guardada</string>
<string name="gameid_saved">Configuración guardada para %1$s</string>
<string name="error_saving">Error guardando %1$s.ini: %2$s</string>
+ <string name="unimplemented_menu">Menú sin implementar</string>
<string name="loading">Cargando...</string>
+ <string name="shutting_down">Saliendo...</string>
<string name="reset_setting_confirmation">¿Desea restablecer esta configuración a su valor predeterminado?</string>
<string name="reset_to_default">Restablecer a predeterminado</string>
<string name="reset_all_settings">¿Restablecer todas las configuraciones?</string>
- <string name="reset_all_settings_description">Todas las configuraciones avanzadas se restablecerán a su configuración predeterminada. Esto no se puede deshacer.</string>
+ <string name="reset_all_settings_description">Todas las opciones avanzadas se restablecerán a su configuración predeterminada. Esta acción no se puede deshacer.</string>
<string name="settings_reset">Reiniciar la configuracion</string>
<string name="close">Cerrar</string>
- <string name="learn_more">Más información</string>
+ <string name="learn_more">Saber más</string>
+ <string name="auto">Auto</string>
+ <string name="submit">Enviar</string>
+ <string name="string_null">Null</string>
+ <string name="string_import">Importar</string>
+ <string name="export">Exportar</string>
+ <string name="export_failed">La exportación falló</string>
+ <string name="import_failed">La importación falló</string>
+ <string name="cancelling">Cancelando</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Seleccionar driver GPU</string>
@@ -172,6 +237,7 @@
<string name="select_gpu_driver_install">Instalar</string>
<string name="select_gpu_driver_default">Predeterminado</string>
<string name="select_gpu_driver_use_default">Usando el driver de GPU por defecto </string>
+ <string name="select_gpu_driver_error">¡Driver no válido, utilizando el predeterminado del sistema!</string>
<string name="system_gpu_driver">Driver GPU del sistema</string>
<string name="installing_driver">Instalando driver...</string>
@@ -182,10 +248,11 @@
<string name="preferences_graphics">Gráficos</string>
<string name="preferences_audio">Audio</string>
<string name="preferences_theme">Tema y color</string>
+ <string name="preferences_debug">Depuración</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Su ROM está encriptada</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga las guías para redumpear <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">cartuchos de juegos</a> o <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">titulos instalados</a>.]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga las guías para redumpear<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartuchos de juegos</a> o <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">títulos instalados</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Por favor, compruebe que su archivo <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado, para que los juegos sean descifrados.]]></string>
<string name="loader_error_video_core">Ocurrió un error al inicializar el núcleo de video, posiblemente debido a una incompatibilidad con el driver seleccionado</string>
<string name="loader_error_video_core_description">Esto suele deberse a un driver de GPU incompatible. La instalación de un controlador de GPU personalizado puede resolver este problema.</string>
@@ -196,25 +263,25 @@
<string name="emulation_exit">Salir de la emulación</string>
<string name="emulation_done">Hecho</string>
<string name="emulation_fps_counter">Contador de FPS</string>
- <string name="emulation_toggle_controls">Alternar Controles</string>
- <string name="emulation_rel_stick_center">Centro Relativo del Stick</string>
- <string name="emulation_dpad_slide">Deslizamiento de la Cruceta</string>
- <string name="emulation_haptics">Hápticos</string>
- <string name="emulation_show_overlay">Mostrar pantalla</string>
- <string name="emulation_toggle_all">Alternar Todo</string>
- <string name="emulation_control_adjust">Ajustar pantalla</string>
+ <string name="emulation_toggle_controls">Alternar controles</string>
+ <string name="emulation_rel_stick_center">Centro relativo del stick</string>
+ <string name="emulation_dpad_slide">Deslizamiento de la cruceta</string>
+ <string name="emulation_haptics">Toques hápticos</string>
+ <string name="emulation_show_overlay">Mostrar overlay</string>
+ <string name="emulation_toggle_all">Alternar todo</string>
+ <string name="emulation_control_adjust">Ajustar overlay</string>
<string name="emulation_control_scale">Escala</string>
<string name="emulation_control_opacity">Opacidad</string>
- <string name="emulation_touch_overlay_reset">Reiniciar pantalla</string>
- <string name="emulation_touch_overlay_edit">Editar pantalla</string>
- <string name="emulation_pause">Pausar Emulación</string>
- <string name="emulation_unpause">Reanudar Emulación</string>
- <string name="emulation_input_overlay">Opciones de pantalla </string>
+ <string name="emulation_touch_overlay_reset">Reiniciar overlay</string>
+ <string name="emulation_touch_overlay_edit">Editar overlay</string>
+ <string name="emulation_pause">Pausar emulación</string>
+ <string name="emulation_unpause">Despausar emulación</string>
+ <string name="emulation_input_overlay">Opciones de overlay</string>
<string name="load_settings">Cargando configuración...</string>
<!-- Software keyboard -->
- <string name="software_keyboard">Software del teclado</string>
+ <string name="software_keyboard">Teclado de software</string>
<!-- Errors and warnings -->
<string name="abort_button">Abortar</string>
@@ -226,6 +293,9 @@
<string name="fatal_error">Error fatal</string>
<string name="fatal_error_message">Ocurrió un error fatal. Consulte el registro para obtener más detalles.\nContinuar con la emulación puede provocar bloqueos y errores.</string>
<string name="performance_warning">¡Desactivar esta configuración reducirá significativamente el rendimiento de la emulación! Para obtener la mejor experiencia, se recomienda dejar esta configuración habilitada.</string>
+ <string name="device_memory_inadequate">RAM de dispositivo: %1$s\nRecomendado: %2$s</string>
+ <string name="memory_formatted">%1$s %2$s</string>
+ <string name="no_game_present">¡No hay ningún juego ejecutable presente!</string>
<!-- Region Names -->
<string name="region_japan">Japón</string>
@@ -236,7 +306,14 @@
<string name="region_korea">Corea</string>
<string name="region_taiwan">Taiwán</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +351,11 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">Paisaje</string>
+ <string name="screen_layout_portrait">Retrato</string>
+ <string name="screen_layout_auto">Auto</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Predeterminado (16:9)</string>
<string name="ratio_force_four_three">Forzar 4:3</string>
@@ -298,7 +380,7 @@
<string name="building_shaders">Construyendo shaders</string>
<!-- Theme options -->
- <string name="change_app_theme">Cambiar Tema</string>
+ <string name="change_app_theme">Cambiar tema</string>
<string name="theme_default">Predeterminado</string>
<string name="theme_material_you">Material You</string>
@@ -308,8 +390,22 @@
<string name="theme_mode_light">Claro</string>
<string name="theme_mode_dark">Oscuro</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Usar Fondos Negros</string>
+ <string name="use_black_backgrounds">Fondos oscuros</string>
<string name="use_black_backgrounds_description">Cuando utilice el modo oscuro, aplique fondos negros.</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Picture in Picture</string>
+ <string name="picture_in_picture_description">Minimizar ventana cuando esté en segundo plano</string>
+ <string name="pause">Pausar</string>
+ <string name="play">Jugar</string>
+ <string name="mute">Mutear</string>
+ <string name="unmute">Desmutear</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Licencias</string>
+ <string name="license_fidelityfx_fsr_description">Upscaling de alta calidad de AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml
index 1e02828aa..5a827c50b 100644
--- a/src/android/app/src/main/res/values-fr/strings.xml
+++ b/src/android/app/src/main/res/values-fr/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">Ce logiciel exécutera des jeux pour la console de jeu Nintendo Switch. Aucun jeux ou clés n\'est inclus.&lt;br /&gt;&lt;br /&gt;Avant de commencer, veuillez localiser votre fichier <![CDATA[<b> prod.keys </b>]]> sur le stockage de votre appareil.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">En savoir plus</a>]]></string>
<string name="emulation_notification_channel_name">L\'émulation est active</string>
@@ -19,12 +19,13 @@
<string name="games">Jeux</string>
<string name="games_description">Sélectionnez votre dossier &lt;b>de Jeux&lt;/b> avec le bouton ci-dessous.</string>
<string name="done">Terminé</string>
- <string name="done_description">Vous êtes prêt.\nProfitez de vos jeux !</string>
+ <string name="done_description">Vous êtes prêt.\nProfitez de vos jeux !</string>
<string name="text_continue">Continuer</string>
<string name="next">Suivant</string>
<string name="back">Retour</string>
<string name="add_games">Ajouter des jeux</string>
- <string name="add_games_description">Sélectionner votre dossier de jeux</string>
+ <string name="add_games_description">Sélectionner le dossier des jeux</string>
+ <string name="step_complete">Terminé !</string>
<!-- Home strings -->
<string name="home_games">Jeux</string>
@@ -32,12 +33,13 @@
<string name="home_settings">Paramètres</string>
<string name="empty_gamelist">Aucun fichier n\'a été trouvé ou aucun répertoire de jeu n\'a encore été sélectionné.</string>
<string name="search_and_filter_games">Rechercher et filtrer les jeux</string>
- <string name="select_games_folder">Sélectionner le dossier de jeux</string>
+ <string name="select_games_folder">Sélectionner le dossier des jeux</string>
<string name="select_games_folder_description">Permet à yuzu de remplir la liste des jeux</string>
- <string name="add_games_warning">Ne pas sélectionner le dossier des jeux ?</string>
+ <string name="add_games_warning">Ne pas sélectionner le dossier des jeux ?</string>
<string name="add_games_warning_description">Les jeux ne seront pas affichés dans la liste des jeux si aucun dossier n\'est sélectionné.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">Rechercher des jeux</string>
+ <string name="search_settings">Rechercher un paramètre</string>
<string name="games_dir_selected">Répertoire de jeux sélectionné</string>
<string name="install_prod_keys">Installer prod.keys</string>
<string name="install_prod_keys_description">Nécessaire pour décrypter les jeux commerciaux.</string>
@@ -46,7 +48,7 @@
<string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
<string name="notifications">Notifications</string>
<string name="notifications_description">Accordez l\'autorisation de notification avec le bouton ci-dessous.</string>
- <string name="give_permission">Donner la permission</string>
+ <string name="give_permission">Accorder la permission</string>
<string name="notification_warning">Ne pas accorder la permission de notification ?</string>
<string name="notification_warning_description">yuzu ne pourra pas vous communiquer d\'informations importantes.</string>
<string name="permission_denied">Permission refusée</string>
@@ -61,12 +63,15 @@
<string name="invalid_keys_file">Fichier de clés sélectionné invalide</string>
<string name="install_keys_success">Clés installées avec succès</string>
<string name="reading_keys_failure">Erreur lors de la lecture des clés de chiffrement</string>
+ <string name="install_prod_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .keys et réessayez.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .bin et réessayez.</string>
<string name="invalid_keys_error">Clés de chiffrement invalides</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">Le fichier sélectionné est incorrect ou corrompu. Veuillez dumper à nouveau vos clés.</string>
<string name="install_gpu_driver">Installer le pilote du GPU</string>
- <string name="install_gpu_driver_description">Installez des pilotes alternatifs pour des performances ou une précision potentiellement meilleures</string>
+ <string name="install_gpu_driver_description">Installer des pilotes alternatifs pour des performances ou une précision potentiellement meilleures</string>
<string name="advanced_settings">Paramètres avancés</string>
+ <string name="advanced_settings_game">Paramètres avancés : %1$s</string>
<string name="settings_description">Configurer les paramètres de l\'émulateur</string>
<string name="search_recently_played">Joué récemment</string>
<string name="search_recently_added">Ajouté récemment</string>
@@ -86,6 +91,33 @@
<string name="save_file_invalid_zip_structure_description">Le nom du premier sous-dossier doit être l\'identifiant du titre du jeu.</string>
<string name="import_saves">Importer</string>
<string name="export_saves">Exporter</string>
+ <string name="install_firmware">Installer le firmware</string>
+ <string name="install_firmware_description">Le firmware doit être dans une archive ZIP et est nécessaire pour démarrer certains jeux.</string>
+ <string name="firmware_installing">Installation du firmware</string>
+ <string name="firmware_installed_success">Firmware installé avec succès</string>
+ <string name="firmware_installed_failure">L\'installation du firmware a échoué</string>
+ <string name="firmware_installed_failure_description">Assurez-vous que les fichiers NCA du firmware se trouvent à la racine du fichier ZIP, puis réessayez.</string>
+ <string name="share_log">Partager les logs de débogage</string>
+ <string name="share_log_description">Partagez le fichier de log de yuzu pour déboguer les problèmes.</string>
+ <string name="share_log_missing">Aucun fichier de log trouvé</string>
+ <string name="install_game_content">Installer le contenu du jeu</string>
+ <string name="install_game_content_description">Installer une mise à jour ou un DLC</string>
+ <string name="installing_game_content">Installation du contenu en cours...</string>
+ <string name="install_game_content_failure">Erreur lors de l\'installation du fichier dans la NAND</string>
+ <string name="install_game_content_failure_description">Veuillez vous assurer que le contenu est valide et que le fichier prod.keys est installé.</string>
+ <string name="install_game_content_failure_base">L\'installation de jeux de base n\'est pas autorisée afin d\'éviter d\'éventuels conflits.</string>
+ <string name="install_game_content_failure_file_extension">Seuls les contenus NSP et XCI sont pris en charge. Veuillez vérifier que le contenu du jeu est valide.</string>
+ <string name="install_game_content_failed_count">%1$d erreur(s) d\'installation</string>
+ <string name="install_game_content_success">Contenu du jeu installé avec succès</string>
+ <string name="install_game_content_success_install">%1$d installé avec succès</string>
+ <string name="install_game_content_success_overwrite">%1$d écrasé avec succès</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">Pilotes personnalisés non supporté</string>
+ <string name="custom_driver_not_supported_description">Le chargement des pilotes personnalisés ne sont pas actuellement pris en charge pour ce périphérique. Vérifiez à nouveau cette option à l\'avenir pour voir si la prise en charge a été ajoutée !</string>
+ <string name="manage_yuzu_data">Gérer les données de yuzu</string>
+ <string name="manage_yuzu_data_description">Importer/exporter le firmware, les clés, les données utilisateur, et bien plus encore !</string>
+ <string name="share_save_file">Partager le fichier de sauvegarde</string>
+ <string name="export_save_failed">Échec de l\'exportation de la sauvegarde</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia n\'est pas réel</string>
@@ -94,7 +126,18 @@
<string name="contributors">Contributeurs</string>
<string name="contributors_description">Fait avec \u2764 de l\'équipe yuzu</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Des projets qui rendent possible yuzu pour Android</string>
<string name="build">Build</string>
+ <string name="user_data">Données utilisateur</string>
+ <string name="user_data_description">Importer/exporter toutes les données de l\'application.\n\nLors de l\'importation des données utilisateur, toutes les données utilisateur existantes seront supprimées !</string>
+ <string name="exporting_user_data">Exportation des données utilisateur...</string>
+ <string name="importing_user_data">Importation des données utilisateur...</string>
+ <string name="import_user_data">Importer des données utilisateur</string>
+ <string name="invalid_yuzu_backup">Backup yuzu invalide</string>
+ <string name="user_data_export_success">Les données utilisateur ont été exportés avec succès</string>
+ <string name="user_data_import_success">Les données utilisateur ont été importées avec succès</string>
+ <string name="user_data_export_cancelled">Exportation annulée</string>
+ <string name="user_data_import_failed_description">Assurez-vous que les dossiers de données utilisateur se trouvent à la racine du dossier ZIP et contiennent un fichier de configuration à config/config.ini, puis réessayez.</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,64 +157,87 @@
<string name="are_you_interested">Es tu intéressé ?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Activer la vitesse limite</string>
- <string name="frame_limit_enable_description">Lorsqu\'elle est activée, la vitesse d\'émulation sera limitée à un pourcentage spécifié de la vitesse normale.</string>
+ <string name="frame_limit_enable">Limitation de vitesse</string>
+ <string name="frame_limit_enable_description">Limiter la vitesse d\'émulation à un pourcentage spécifié de la vitesse normale</string>
<string name="frame_limit_slider">Limite en pourcentage de vitesse</string>
- <string name="frame_limit_slider_description">Spécifie le pourcentage pour limiter la vitesse d\'émulation. Avec la valeur par défaut de 100%, l\'émulation sera limitée à la vitesse normale. Des valeurs supérieures ou inférieures augmenteront ou diminueront la limite de vitesse.</string>
+ <string name="frame_limit_slider_description">Spécifier le pourcentage pour limiter la vitesse d\'émulation. 100% correspond à la vitesse normale. Des valeurs plus élevées ou plus basses augmenteront ou diminueront la limite de vitesse.</string>
<string name="cpu_accuracy">Précision du CPU</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
<string name="use_docked_mode">Mode TV</string>
- <string name="use_docked_mode_description">Émuler en mode TV augmente la résolution au détriment des performances.</string>
+ <string name="use_docked_mode_description">Augmenter la résolution, ce qui diminue les performances. Le mode portable est utilisé lorsque la fonction est désactivée, ce qui réduit la résolution et améliore les performances.</string>
<string name="emulated_region">Région émulée</string>
<string name="emulated_language">Langue émulée</string>
<string name="select_rtc_date">Sélectionner la date RTC</string>
<string name="select_rtc_time">Sélectionner l\'heure RTC</string>
- <string name="use_custom_rtc">Activer l\'horloge RTC personnalisée</string>
- <string name="use_custom_rtc_description">Ce paramètre vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string>
+ <string name="use_custom_rtc">RTC personnalisé</string>
+ <string name="use_custom_rtc_description">Vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string>
<string name="set_custom_rtc">Définir l\'horloge RTC personnalisée</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Niveau de précision</string>
- <string name="renderer_resolution">Résolution</string>
+ <string name="renderer_resolution">Résolution (Mode Portable/Mode TV)</string>
<string name="renderer_vsync">Mode VSync</string>
+ <string name="renderer_screen_layout">Orientation</string>
<string name="renderer_aspect_ratio">Format</string>
<string name="renderer_scaling_filter">Filtre de fenêtre adaptatif</string>
- <string name="renderer_anti_aliasing">Méthode d\'anticrénelage :</string>
- <string name="renderer_force_max_clock">Forcer la fréquence d\'horloge maximale (Adreno uniquement)</string>
- <string name="renderer_force_max_clock_description">Force le GPU à fonctionner au maximum d\'horloges possibles (les contraintes thermiques seront toujours appliquées).</string>
+ <string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
+ <string name="renderer_force_max_clock">Forcer les fréquences maximales (Adreno uniquement)</string>
+ <string name="renderer_force_max_clock_description">Forcer le GPU à fonctionner à ses fréquences maximales possibles (les contraintes thermiques seront toujours appliquées).</string>
<string name="renderer_asynchronous_shaders">Utiliser les shaders asynchrones</string>
- <string name="renderer_asynchronous_shaders_description">Compile les shaders de manière asynchrone, ce qui réduira les saccades mais peut entraîner des problèmes visuels.</string>
- <string name="renderer_debug">Activer le débogage des graphismes</string>
- <string name="renderer_debug_description">Lorsque cette case est cochée, l\'API graphique entre dans un mode de débogage plus lent.</string>
- <string name="use_disk_shader_cache">Utiliser les shader cache de disque</string>
- <string name="use_disk_shader_cache_description">Réduire les saccades en stockant et en chargeant les shaders générés sur le disque.</string>
+ <string name="renderer_asynchronous_shaders_description">Compile les shaders de manière asynchrone, réduisant les saccades mais pouvant entraîner des problèmes visuels.</string>
+ <string name="renderer_reactive_flushing">Utiliser le vidage réactif</string>
+ <string name="renderer_reactive_flushing_description">Améliore la précision du rendu dans certains jeux au détriment des performances.</string>
+ <string name="use_disk_shader_cache">Utiliser les shader cache</string>
+ <string name="use_disk_shader_cache_description">Réduire les saccades en stockant et en chargeant localement les shaders générés</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">Débogage du CPU</string>
+ <string name="cpu_debug_mode_description">Place le CPU en mode lent de débogage.</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Débogage des graphismes</string>
+ <string name="renderer_debug_description">Définit l\'API graphique en mode de débogage lent.</string>
+ <string name="fastmem">Fastmem</string>
<!-- Audio settings strings -->
+ <string name="audio_output_engine">Moteur de sortie</string>
<string name="audio_volume">Volume</string>
- <string name="audio_volume_description">Spécifie le volume de la sortie audio.</string>
+ <string name="audio_volume_description">Spécifier le volume de la sortie audio.</string>
<!-- Miscellaneous -->
- <string name="slider_default">Défaut</string>
+ <string name="slider_default">Par défaut</string>
<string name="ini_saved">Paramètres enregistrés</string>
<string name="gameid_saved">Paramètres enregistrés pour %1$s</string>
<string name="error_saving">Erreur lors de l\'enregistrement de %1$s.ini: %2$s</string>
+ <string name="unimplemented_menu">Menu non implémenté</string>
<string name="loading">Chargement...</string>
- <string name="reset_setting_confirmation">Voulez-vous réinitialiser ce paramètre à sa valeur par défaut ?</string>
+ <string name="shutting_down">Extinction en cours...</string>
+ <string name="reset_setting_confirmation">Voulez-vous réinitialiser ce paramètre à sa valeur par défaut ?</string>
<string name="reset_to_default">Réinitialiser par défaut</string>
<string name="reset_all_settings">Réinitialiser tous les réglages ?</string>
<string name="reset_all_settings_description">Tous les paramètres avancés seront réinitialisés à leur configuration par défaut. Ça ne peut pas être annulé.</string>
<string name="settings_reset">Paramètres réinitialisés</string>
<string name="close">Fermer</string>
- <string name="learn_more">Plus d\'informations</string>
+ <string name="learn_more">En savoir plus</string>
+ <string name="auto">Auto</string>
+ <string name="submit">Soumettre</string>
+ <string name="string_null">Nul</string>
+ <string name="string_import">Importer</string>
+ <string name="export">Exporter</string>
+ <string name="export_failed">L\'exportation a échoué</string>
+ <string name="import_failed">L\'importation a échoué</string>
+ <string name="cancelling">Annulation</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Sélectionner le pilote du GPU</string>
<string name="select_gpu_driver_title">Souhaitez vous remplacer votre pilote actuel ?</string>
<string name="select_gpu_driver_install">Installer</string>
- <string name="select_gpu_driver_default">Défaut</string>
- <string name="select_gpu_driver_use_default">Utilisation du pilote de GPU par défaut</string>
+ <string name="select_gpu_driver_default">Par défaut</string>
+ <string name="select_gpu_driver_use_default">Utilisation du pilote du GPU par défaut</string>
+ <string name="select_gpu_driver_error">Pilote non valide sélectionné, utilisation du paramètre par défaut du système !</string>
<string name="system_gpu_driver">Pilote du GPU du système</string>
<string name="installing_driver">Installation du pilote...</string>
@@ -182,13 +248,14 @@
<string name="preferences_graphics">Vidéo</string>
<string name="preferences_audio">Audio</string>
<string name="preferences_theme">Thème et couleur</string>
+ <string name="preferences_debug">Débogage</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Votre ROM est cryptée</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Veuillez suivre les guides pour redumper vos <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">cartouches de jeu</a> ou <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">titres installés</a>.]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[Veuillez suivre les guides pour refaire un dump de vos <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartouches de jeu</a> ou de vos <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">titres installés</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Veuillez vous assurer que votre fichier <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> est installé pour que les jeux puissent être déchiffrés.]]></string>
<string name="loader_error_video_core">Une erreur s\'est produite lors de l\'initialisation du noyau vidéo</string>
- <string name="loader_error_video_core_description">Cela est généralement dû à un pilote du GPU incompatible. L\'installation d\'un pilote du GPU personnalisé peut résoudre ce problème.</string>
+ <string name="loader_error_video_core_description">Cela est généralement dû à un pilote GPU incompatible. L\'installation d\'un pilote GPU personnalisé peut résoudre ce problème.</string>
<string name="loader_error_invalid_format">Impossible de charger la ROM</string>
<string name="loader_error_file_not_found">Le fichier ROM n\'existe pas</string>
@@ -198,8 +265,8 @@
<string name="emulation_fps_counter">Compteur FPS</string>
<string name="emulation_toggle_controls">Activer/Désactiver les contrôles</string>
<string name="emulation_rel_stick_center">Centre du stick relatif</string>
- <string name="emulation_dpad_slide">Glissement du DPad</string>
- <string name="emulation_haptics">Haptique</string>
+ <string name="emulation_dpad_slide">Glissement du D-pad</string>
+ <string name="emulation_haptics">Toucher haptique</string>
<string name="emulation_show_overlay">Afficher l\'overlay</string>
<string name="emulation_toggle_all">Tout basculer</string>
<string name="emulation_control_adjust">Ajuster l\'overlay</string>
@@ -225,7 +292,10 @@
<string name="save_load_error">Erreur de sauvegarde/chargement</string>
<string name="fatal_error">Erreur fatale</string>
<string name="fatal_error_message">Une erreur fatale s\'est produite. Consultez les logs pour plus de détails.\nContinuer l\'émulation peut entraîner des plantages et des bogues.</string>
- <string name="performance_warning">La désactivation de ce paramètre réduira considérablement les performances d\'émulation ! Pour une expérience optimale, il est recommandé de laisser ce paramètre activé.</string>
+ <string name="performance_warning">La désactivation de ce paramètre réduira considérablement les performances d\'émulation ! Pour une expérience optimale, il est recommandé de laisser ce paramètre activé.</string>
+ <string name="device_memory_inadequate">Mémoire RAM de l\'appareil : %1$s\nRecommandé : %2$s</string>
+ <string name="memory_formatted">%1$s %2$s</string>
+ <string name="no_game_present">Aucun jeu démarreable présent !</string>
<!-- Region Names -->
<string name="region_japan">Japon</string>
@@ -236,7 +306,14 @@
<string name="region_korea">Corée</string>
<string name="region_taiwan">Taïwan</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Octet</string>
+ <string name="memory_kilobyte">Ko</string>
+ <string name="memory_megabyte">Mo</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">To</string>
+ <string name="memory_petabyte">Po</string>
+ <string name="memory_exabyte">Eo</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +351,11 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">Paysage</string>
+ <string name="screen_layout_portrait">Portrait</string>
+ <string name="screen_layout_auto">Auto</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Par défaut (16:9)</string>
<string name="ratio_force_four_three">Forcer le 4:3</string>
@@ -288,8 +370,8 @@
<!-- Gamepad Buttons -->
<string name="gamepad_d_pad">Pavé directionnel</string>
- <string name="gamepad_left_stick">Stick Gauche</string>
- <string name="gamepad_right_stick">Stick Droit</string>
+ <string name="gamepad_left_stick">Stick gauche</string>
+ <string name="gamepad_right_stick">Stick droit</string>
<string name="gamepad_home">Home</string>
<string name="gamepad_screenshot">Capture d\'écran</string>
@@ -299,7 +381,7 @@
<!-- Theme options -->
<string name="change_app_theme">Changer le thème de l\'application</string>
- <string name="theme_default">Défaut</string>
+ <string name="theme_default">Par défaut</string>
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
@@ -308,8 +390,22 @@
<string name="theme_mode_light">Lumineux</string>
<string name="theme_mode_dark">Sombre</string>
- <!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Utiliser des arrière-plans noirs</string>
- <string name="use_black_backgrounds_description">Lorsque vous utilisez le thème sombre, appliquer des arrière-plans noirs.</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
-</resources>
+ <!-- Black backgrounds theme -->
+ <string name="use_black_backgrounds">Arrière-plan noir</string>
+ <string name="use_black_backgrounds_description">Lorsque vous utilisez le thème sombre, appliquer un arrière-plan noir.</string>
+
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Lecteur réduit</string>
+ <string name="picture_in_picture_description">Réduire la fenêtre lorsqu\'elle est placée en arrière-plan</string>
+ <string name="pause">Pause</string>
+ <string name="play">Jouer</string>
+ <string name="mute">Couper le son</string>
+ <string name="unmute">Remettre le son</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Licences</string>
+ <string name="license_fidelityfx_fsr_description">Mise à l\'échelle de haute qualité par AMD.</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-he/strings.xml b/src/android/app/src/main/res/values-he/strings.xml
new file mode 100644
index 000000000..0af78a57c
--- /dev/null
+++ b/src/android/app/src/main/res/values-he/strings.xml
@@ -0,0 +1,367 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
+
+ <string name="app_disclaimer">התוכנה תריץ משחקים לקונסולת ה Nintendo Switch. אף משחק או קבצים בעלי זכויות יוצרים נכללים.&lt;br /&gt;&lt;br /&gt; לפני שאת/ה מתחיל בבקשה מצא את קובץ <![CDATA[<b>prod.keys</b>]]> על המכשיר.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">קרא עוד</a>]]></string>
+ <string name="emulation_notification_channel_name">אמולציה פעילה</string>
+ <string name="emulation_notification_channel_description">מציג התראה מתמשכת כאשר האמולציה פועלת.</string>
+ <string name="emulation_notification_running">yuzu רץ</string>
+ <string name="notice_notification_channel_name">התראות ותקלות</string>
+ <string name="notice_notification_channel_description">מציג התראות כאשר משהו הולך לא כשורה.</string>
+ <string name="notification_permission_not_granted">הרשאות התראות לא ניתנה!</string>
+
+ <!-- Setup strings -->
+ <string name="welcome">ברוכים הבאים!</string>
+ <string name="welcome_description">למד איך להפעיל &lt;b>yuzu&lt;/b> וקפוץ ישר לאמולציה.</string>
+ <string name="get_started">כדי להתחיל</string>
+ <string name="keys">מפתחות</string>
+ <string name="keys_description">בחר את קובץ ה &lt;b>prod.keys&lt;/b> שלך עם הכפתור למטה.</string>
+ <string name="select_keys">בחר מפתחות</string>
+ <string name="games">משחקים</string>
+ <string name="games_description">בחר את התיקיית ה &lt;b>Games&lt;/b> שלך עם הכפתור למטה.</string>
+ <string name="done">סיום</string>
+ <string name="done_description">את/ה מוכן. \nתהנה/י מהמשחקים שלך </string>
+ <string name="text_continue">המשך</string>
+ <string name="next">הבא</string>
+ <string name="back">אחורה</string>
+ <string name="add_games">הוסף משחקים</string>
+ <string name="add_games_description">בחר/י את תיקיית המשחקים שלך</string>
+ <string name="step_complete">הושלם!</string>
+
+ <!-- Home strings -->
+ <string name="home_games">משחקים</string>
+ <string name="home_search">חפש</string>
+ <string name="home_settings">הגדרות</string>
+ <string name="empty_gamelist">לא נמצאו קבצים או לנבחרה ספריית קבצים בינתיים.</string>
+ <string name="search_and_filter_games">חפש וסנן משחקים</string>
+ <string name="select_games_folder">בחר תיקיית משחקים</string>
+ <string name="select_games_folder_description">אפשר ל yuzu לאכלס את רשימת המשחקים</string>
+ <string name="add_games_warning">לדלג על בחירת תיקיית המשחקים?</string>
+ <string name="add_games_warning_description">משחקים לא יוצגו ברשימת המשחקים אם לנבחרה תיקיית משחקים.</string>
+ <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
+ <string name="home_search_games">חפש משחקים</string>
+ <string name="search_settings">חפש בהגדרות</string>
+ <string name="games_dir_selected">ספריית משחקים נבחרה</string>
+ <string name="install_prod_keys">התקן prod.keys</string>
+ <string name="install_prod_keys_description">הכרחי בכדי לפענח משחקים</string>
+ <string name="install_prod_keys_warning">לדלג על הוספת מפתחות?</string>
+ <string name="install_prod_keys_warning_description">מפתחות חוקיים הכרחיים כדי לשחק במשחקים. רק אפליקציות פירטיות יפעלו אם תמשיך.</string>
+ <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
+ <string name="notifications">התראות</string>
+ <string name="notifications_description">תן גישה להתראות עם הכפתור למטה.</string>
+ <string name="give_permission">תן הרשאה</string>
+ <string name="notification_warning">דלג על מתן הרשאה להתראות?</string>
+ <string name="notification_warning_description">yuzu לא יוכל להתריע לך על מידע חשוב.</string>
+ <string name="permission_denied">הרשאה נדחתה</string>
+ <string name="permission_denied_description">את/ה דיחת את ההרשאה יותר מדי פעמים ועכשיו את/ה צריך/ה לתת גישה באופן ידני בהגדרות.</string>
+ <string name="about">אודות</string>
+ <string name="about_description">מספר גירסה, קרדיטים ועוד</string>
+ <string name="warning_help">עזרה</string>
+ <string name="warning_skip">דלג</string>
+ <string name="warning_cancel">ביטול</string>
+ <string name="install_amiibo_keys">התקן מפתחות Amiibo</string>
+ <string name="install_amiibo_keys_description">נחוץ כדי להשתמש ב Amiibo במשחק</string>
+ <string name="invalid_keys_file">קובץ מפתחות לא חוקי נבחר</string>
+ <string name="install_keys_success">מפתחות הותקנו בהצלחה</string>
+ <string name="reading_keys_failure">שגיאה בקריאת מפתחות ההצפנה</string>
+ <string name="install_prod_keys_failure_extension_description">ודא שלקובץ המפתחות שלך יש סיומת של key. ונסה/י שוב.</string>
+ <string name="install_amiibo_keys_failure_extension_description">ודא/י שלקובץ המפתחות שלך יש סיומת של bin. ונסה/י שוב.</string>
+ <string name="invalid_keys_error">מפתחות הצפנה לא חוקיים</string>
+ <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
+ <string name="install_keys_failure_description">קבוץ שנבחר מושחת או לא נכון. בבקשה הוצא מחדש את המפתחות שלך.</string>
+ <string name="install_gpu_driver">התקן דרייבר למעבד הגרפי</string>
+ <string name="install_gpu_driver_description">התקן דרייברים אחרים בשביל סיכוי לביצועים או דיוק גבוההים יותר</string>
+ <string name="advanced_settings">הגדרות מתקדמות</string>
+ <string name="advanced_settings_game">הגדרות מתקדמות: %1$s</string>
+ <string name="settings_description">הדר את הגדרות האמולטור</string>
+ <string name="search_recently_played">שוחק לאחרונה</string>
+ <string name="search_recently_added">הוסף לאחרונה</string>
+ <string name="search_retail">קמעונאי</string>
+ <string name="search_homebrew">Homebrew</string>
+ <string name="open_user_folder">פתח את תיקיית yuzu </string>
+ <string name="open_user_folder_description">נה ל את הקבצים הפנימיין של yuzu</string>
+ <string name="theme_and_color_description">ערוך את נראות האפליקציה</string>
+ <string name="no_file_manager">לא נמצא מנהל קבצים</string>
+ <string name="notification_no_directory_link">לא יכול לפתוח את ספריית yuzu</string>
+ <string name="notification_no_directory_link_description">בבקשה מקם את תיקיית המשתמש בפנל הצידי של מנהל הקבצים באופן ידני.</string>
+ <string name="manage_save_data">נהל מידע שמור</string>
+ <string name="manage_save_data_description">מידע שמור לא נמצא. בבקשה בחר/י אופציה מלמטה</string>
+ <string name="import_export_saves_description">יבא או יצא קבצי שמירה</string>
+ <string name="save_file_imported_success">יובא בהצלחה</string>
+ <string name="save_file_invalid_zip_structure">מבנה ספריית השמירות לא חוקי</string>
+ <string name="save_file_invalid_zip_structure_description">התת תיקייה הראשונה חייב להיות ה title ID של המשחק</string>
+ <string name="import_saves">ייבוא</string>
+ <string name="export_saves">ייצוא</string>
+ <string name="install_firmware">התקן firmware</string>
+ <string name="install_firmware_description">ה frimware חייב להיות בקובץ zip והוא הכרחי להפעלת חלק מהמשחקים</string>
+ <string name="firmware_installing">מתקין frimware</string>
+ <string name="firmware_installed_success">ה frimware הותקן בהצלחה</string>
+ <string name="firmware_installed_failure">התקנת ה frimware נכשלה</string>
+ <string name="firmware_installed_failure_description">ודא שקבצי ה firmware nca נמצאים בשורש ה zip ונסה שוב.</string>
+ <string name="share_log">שתף את יומני הרישום של מיפוי הבאגים</string>
+ <string name="share_log_description">שתף את קובץ יומני הרישום של yuzu בכדי לתקן בעיות</string>
+ <string name="share_log_missing">לא נמצא קובץ יומן רישום</string>
+ <string name="install_game_content">התקן תוכן משחק</string>
+ <string name="install_game_content_description">התקן עדכוני משחק או DLC</string>
+ <string name="installing_game_content">מתקין תוכן...</string>
+ <string name="install_game_content_failure">תקלה בהתקנת הקובץ (או קבצים) ל NAND</string>
+ <string name="install_game_content_failure_description">בבקשה ודא שהתוכן (או תכנים) חוקיים ושקובץ ה prod.keys מותקן.</string>
+ <string name="install_game_content_failure_base">התקנת משחק בסיס נדחת בכדי להימנע מקונפליקטים אפשריים.</string>
+ <string name="install_game_content_failure_file_extension">רק קבצי NSP ו XCI נתמכים. בבקשה ודא שתוכן (או תכנים) המשחק חוקי.</string>
+ <string name="install_game_content_failed_count">%1$dבעיה (בעיות) התקנה</string>
+ <string name="install_game_content_success">תוכן (או תכני) המשחק הותקנו בהצלחה</string>
+ <string name="install_game_content_success_install">%1$d הותקן בהצלחה</string>
+ <string name="install_game_content_success_overwrite">%1$d נדרס/נכתב מעל בהצלחה</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">דרייברים מותאמים אישית לא נתמכים</string>
+ <string name="custom_driver_not_supported_description">הטענת דרייבים מותאמים אישית לא נתמך כרגע על מכשיר זה. \nבבקשה בדוק אופציה זו בעתיד בכדי לראות אם נוספה תמיכה!</string>
+ <string name="manage_yuzu_data">נהל את המידע של yuzu</string>
+ <string name="manage_yuzu_data_description">יבא/יצא firmware, keys, מידע של משתמש ועוד!</string>
+ <string name="share_save_file">שתף קובץ שמירה</string>
+ <string name="export_save_failed">נכשל בייצוא שמירה</string>
+
+ <!-- About screen strings -->
+ <string name="gaia_is_not_real">Gaia לא אמיתית</string>
+ <string name="copied_to_clipboard">הועתק ללוח</string>
+ <string name="about_app_description">אמולטור Switch עם קוד פתוח</string>
+ <string name="contributors">תורמים</string>
+ <string name="contributors_description">נוצר עם \u2764 מקבוצת yuzu</string>
+ <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">פרוייקטים שהופכים את yuzu ל Android אפשרי</string>
+ <string name="build">גרסה</string>
+ <string name="user_data">נתוני משתמש</string>
+ <string name="user_data_description">יבא/יצא את כל נתוני האפליקציה.\n\nכאשר מייבאים את נתוני המשתמש, כל נתוני המשתמש הקיימים ימחקו!</string>
+ <string name="exporting_user_data">מייצא נתוני משתמש...</string>
+ <string name="importing_user_data">מייבא נתוני משתמש...</string>
+ <string name="import_user_data">יבא נתוני משתמש</string>
+ <string name="invalid_yuzu_backup">גיבוי yuzu לא חוקי</string>
+ <string name="user_data_export_success">נתוני משתמש יוצאו בהצלחה</string>
+ <string name="user_data_import_success">נתוני משתמש יובאו בהצלחה</string>
+ <string name="user_data_export_cancelled">ייצוא בוטל</string>
+ <string name="user_data_import_failed_description">ודא שנתוני המשתמש נמצאים בשורש קובץ ה zip ושהוא מכיל קובץ סידור ב config/config.ini ונסה שוב.</string>
+ <string name="support_link">https://discord.gg/u77vRWY</string>
+ <string name="website_link">https://yuzu-emu.org/</string>
+ <string name="github_link">https://github.com/yuzu-emu</string>
+
+ <!-- Early access upgrade strings -->
+ <string name="early_access">גישה מוקדמת</string>
+ <string name="get_early_access">קבל גישה מוקדמת</string>
+ <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
+ <string name="get_early_access_description">תכונות חותכות קצה, גישה מוקדמת לעדכונים, ועוד</string>
+ <string name="early_access_benefits">יתרונות של גישה מקודמת</string>
+ <string name="cutting_edge_features">תכונות חותכות קצה</string>
+ <string name="early_access_updates">גישה מוקדמת לעדכונים</string>
+ <string name="no_manual_installation">ללא התקנה ידנית</string>
+ <string name="prioritized_support">תמיכה בעדיפות</string>
+ <string name="helping_game_preservation">עוזר בשמירת משחקים</string>
+ <string name="our_eternal_gratitude">התודה האינסופית שלנו</string>
+ <string name="are_you_interested">אתה מעוניין?</string>
+
+ <!-- General settings strings -->
+ <string name="frame_limit_enable">הגבל מהירות</string>
+ <string name="frame_limit_enable_description">מגביל את מהירות האמולציה לאחוז מהירות המבוקש מהמהירות הרגילה.</string>
+ <string name="frame_limit_slider">הגבל את אחוז המהירות</string>
+ <string name="frame_limit_slider_description">מדייק את אחוז מהירות האמולציה. 100% זה מהירות רגילה. ערכים גדולים או קטנים יאיצו או יאטו את מהירות האמולציה.</string>
+ <string name="cpu_accuracy">דיוק המעבד</string>
+ <string name="value_with_units">%1$s%2$s</string>
+
+ <!-- System settings strings -->
+ <string name="use_docked_mode">מצב עגינה</string>
+ <string name="use_docked_mode_description">מעלה את הרזולוציה, פוגע בביצועים. משתמש במצב נייד כאשר מנוטרל, מפחית את הרזולוציה ומעלה את הביצועים.</string>
+ <string name="emulated_region">אזור אמולציה</string>
+ <string name="emulated_language">שפת אמולציה</string>
+ <string name="select_rtc_date">בחר תאריך RTC</string>
+ <string name="select_rtc_time">בחר זמן RTC</string>
+ <string name="use_custom_rtc">RTC מותאם אישית</string>
+ <string name="use_custom_rtc_description">מאפשר לך לקבוע שעון זמן אמת נפרד משעון המערכת שלך.</string>
+ <string name="set_custom_rtc">קבע RTC מותאם אישית</string>
+
+ <!-- Graphics settings strings -->
+ <string name="renderer_accuracy">רמת דיוק</string>
+ <string name="renderer_resolution">רזולוציה (מעוגן/נייד)</string>
+ <string name="renderer_vsync">מצב VSync</string>
+ <string name="renderer_screen_layout">כיוון</string>
+ <string name="renderer_aspect_ratio">יחס רוחב גובה</string>
+ <string name="renderer_scaling_filter">פילטר מתאם חלון</string>
+ <string name="renderer_anti_aliasing">שיטת Anti-aliasing</string>
+ <string name="renderer_force_max_clock">החזק מהירות שעון מקסימלית (רק ל Adreno)</string>
+ <string name="renderer_force_max_clock_description">מכריח לדחוף את מהירויות המעבד הגרפי למקסימום (הגבלות חום ימשיכו לתפקד).</string>
+ <string name="renderer_reactive_flushing_description">משפר את הדיוק של האמולציה במשחקים מסויימים במחיר של ביצועים.</string>
+ <!-- Debug settings strings -->
+ <string name="cpu">מעבד</string>
+ <string name="cpu_debug_mode_description">מכניס את המעבד למצב דיבאג איטי</string>
+ <string name="gpu">מעבד גרפי</string>
+ <!-- Audio settings strings -->
+ <string name="audio_output_engine">מנוע פלט</string>
+ <string name="audio_volume">עוצמת שמע</string>
+ <!-- Miscellaneous -->
+ <string name="slider_default">ברירת מחדל</string>
+ <string name="ini_saved">הגדרות שמורות</string>
+ <string name="gameid_saved">הגדרות שמורות עבור %1$s</string>
+ <string name="error_saving">תקלה בשמירת %1$s.ini: %2$s</string>
+ <string name="loading">טוען...</string>
+ <string name="shutting_down">כיבוי...</string>
+ <string name="reset_setting_confirmation">אתה מעוניין לאפס את ההגדרה הזו חזרה לברירת המחדל?</string>
+ <string name="reset_to_default">אפס לברירת המחדל</string>
+ <string name="reset_all_settings">לאפס את כל ההגדרות?</string>
+ <string name="reset_all_settings_description">כל ההגדרות המתקדמות יאופסו לברירת המחדל. לא ניתן לבטל פעולה זו.</string>
+ <string name="settings_reset">אפס הגדרות</string>
+ <string name="close">סגור</string>
+ <string name="learn_more">למד עוד</string>
+ <string name="auto">אוטומטי</string>
+ <string name="submit">שלח</string>
+ <string name="string_import">ייבוא</string>
+ <string name="export">ייצוא</string>
+ <string name="export_failed">ייצוא נכשל</string>
+ <string name="import_failed">ייבוא נכשל</string>
+ <string name="cancelling">מבטל</string>
+
+ <!-- GPU driver installation -->
+ <string name="select_gpu_driver">בחר דרייבר למעבד הגרפי</string>
+ <string name="select_gpu_driver_title">אתה מעוניין להחליף את הדרייבר של המעבד הגרפי שלך?</string>
+ <string name="select_gpu_driver_install">התקן</string>
+ <string name="select_gpu_driver_default">ברירת מחדל</string>
+ <string name="select_gpu_driver_use_default">משתמש בדרייבר ברירת המחדל של המעבד הגרפי</string>
+ <string name="select_gpu_driver_error">דרייבר לא חוקי נבחר, משתמש בברירת המחדל של המערכת!</string>
+ <string name="system_gpu_driver">דרייבר של המעבד הגרפי של המערכת</string>
+ <string name="installing_driver">מתקין דרייבר...</string>
+
+ <!-- Preferences Screen -->
+ <string name="preferences_settings">הגדרות</string>
+ <string name="preferences_general">כללי</string>
+ <string name="preferences_system">מערכת</string>
+ <string name="preferences_graphics">גרפיקה</string>
+ <string name="preferences_audio">שמע</string>
+ <string name="preferences_theme">צבע ונושא</string>
+ <!-- ROM loading errors -->
+ <string name="loader_error_encrypted">המשחק שלך מוצפן</string>
+ <string name="loader_error_invalid_format">אין אפשרות לטעון את המשחק</string>
+ <string name="loader_error_file_not_found">קובץ המשחק לא קיים</string>
+
+ <!-- Emulation Menu -->
+ <string name="emulation_exit">צא מהאמולציה</string>
+ <string name="emulation_done">סיום</string>
+ <string name="emulation_fps_counter">סופר FPS</string>
+ <string name="emulation_control_scale">קנה מידה</string>
+ <string name="emulation_control_opacity">שקיפות</string>
+ <string name="emulation_pause">עצור אמולציה</string>
+ <string name="emulation_unpause">המשך אמולציה</string>
+ <string name="load_settings">טוען הגדרות...</string>
+
+ <!-- Software keyboard -->
+ <string name="software_keyboard">מקלדת תוכנה</string>
+
+ <!-- Errors and warnings -->
+ <string name="abort_button">אודות</string>
+ <string name="continue_button">המשך</string>
+ <string name="system_archive_not_found">ארכיון מערכת לא נמצא</string>
+ <string name="system_archive_not_found_message">%s חסר. בבקשה הוצא תא ארכיוני המערכת שלך./nהמשכת האמולציה עלולה לגרום לקריסות ובאגים.</string>
+ <string name="system_archive_general">ארכיון מערכת</string>
+ <string name="save_load_error">בעיית שמירה/טעינה</string>
+ <string name="fatal_error">שגיאה חמורה</string>
+ <string name="device_memory_inadequate">RAM המכשיר: %1$s/nמומלץ: %2$s</string>
+ <string name="memory_formatted">%1$s%2$s</string>
+ <string name="no_game_present">אין משחק שניתן להריץ!</string>
+
+ <!-- Region Names -->
+ <string name="region_japan">יפן</string>
+ <string name="region_usa">ארה״ב</string>
+ <string name="region_europe">אירופה</string>
+ <string name="region_australia">אוסטרליה</string>
+ <string name="region_china">סין</string>
+ <string name="region_korea">קוריאה</string>
+ <string name="region_taiwan">טייוואן</string>
+
+ <!-- Memory Sizes -->
+ <string name="memory_byte">בייט</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
+
+ <!-- Renderer APIs -->
+ <string name="renderer_vulkan">Vulkan</string>
+ <string name="renderer_none">אין שום דבר</string>
+
+ <!-- Renderer Accuracy -->
+ <string name="renderer_accuracy_normal">רגיל</string>
+ <string name="renderer_accuracy_high">גבוה</string>
+ <string name="renderer_accuracy_extreme">אקסטרים (איטי)</string>
+
+ <!-- Resolutions -->
+ <string name="resolution_half">0.5X (360p/540p)</string>
+ <string name="resolution_three_quarter">0.75X (540p/810p)</string>
+ <string name="resolution_one">1X (720p/1080p)</string>
+ <string name="resolution_two">2X (1440p/2160p) (איטי)</string>
+ <string name="resolution_three">3X (2160p/3240p) (איטי)</string>
+ <string name="resolution_four">4X (2880p/4320p) (איטי)</string>
+
+ <string name="renderer_vsync_mailbox">תיבת דואר</string>
+ <string name="renderer_vsync_fifo">FIFO (On)</string>
+ <string name="renderer_vsync_fifo_relaxed">FIFO נינוח</string>
+
+ <!-- Scaling Filters -->
+ <string name="scaling_filter_nearest_neighbor">השכן הקרוב ביותר</string>
+ <string name="scaling_filter_scale_force">ScaleForce</string>
+ <string name="scaling_filter_fsr">AMD FidelityFX™ Super Resolution</string>
+
+ <!-- Anti-Aliasing -->
+ <string name="anti_aliasing_none">אין שום דבר</string>
+ <string name="anti_aliasing_fxaa">FXAA</string>
+ <string name="anti_aliasing_smaa">SMAA</string>
+
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">לרוחב</string>
+ <string name="screen_layout_portrait">לאורך</string>
+ <string name="screen_layout_auto">אוטומטי</string>
+
+ <!-- Aspect Ratios -->
+ <string name="ratio_default">ברירת מחדל (16:9)</string>
+ <string name="ratio_force_four_three">הכרח 4:3</string>
+ <string name="ratio_force_twenty_one_nine">הכרח 21:9</string>
+ <string name="ratio_force_sixteen_ten">הכרח 16:10</string>
+ <string name="ratio_stretch">הרחב לגודל המסך</string>
+
+ <!-- CPU Accuracy -->
+ <string name="cpu_accuracy_accurate">מדויק</string>
+ <string name="cpu_accuracy_unsafe">לא בטוח</string>
+ <string name="cpu_accuracy_paranoid">פראנואידי (איטי)</string>
+
+ <!-- Gamepad Buttons -->
+ <string name="gamepad_d_pad">D-pad</string>
+ <string name="gamepad_left_stick">ג׳ויסטיק שמאלי</string>
+ <string name="gamepad_right_stick">ג׳ויסטיק ימני</string>
+ <string name="gamepad_home">בית</string>
+ <string name="gamepad_screenshot">צילום מסך</string>
+
+ <!-- Theme options -->
+ <string name="change_app_theme">שנה את נושא האפליקצייה</string>
+ <string name="theme_default">ברירת מחדל</string>
+ <string name="theme_material_you">חומר אתה/מאטיריאל יו</string>
+
+ <!-- Theme Modes -->
+ <string name="change_theme_mode">שנה את מצב הנושא</string>
+ <string name="theme_mode_follow_system">עקוב אחרי המערכת</string>
+ <string name="theme_mode_light">בהיר</string>
+ <string name="theme_mode_dark">כהה</string>
+
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
+ <!-- Black backgrounds theme -->
+ <string name="use_black_backgrounds">רקעים שחורים</string>
+ <string name="use_black_backgrounds_description">כשמתשמשים במצב כהה, שם רקעים שחורים.</string>
+
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">תמונה בתוך תמונה</string>
+ <string name="picture_in_picture_description">הקטן את החלון כאשר נמצא ברקע</string>
+ <string name="pause">עצור</string>
+ <string name="play">שחק</string>
+ <string name="mute">השתק</string>
+ <string name="unmute">בטל השתקה</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">רישיונות</string>
+ <string name="license_fidelityfx_fsr_description">אפסקיילינג באיכות גבוהה מ AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-hu/strings.xml b/src/android/app/src/main/res/values-hu/strings.xml
new file mode 100644
index 000000000..6563ba288
--- /dev/null
+++ b/src/android/app/src/main/res/values-hu/strings.xml
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
+
+ <string name="app_disclaimer">Ez a szoftver Nintendo Switch játékkonzolhoz készült játékokat futtat. Nem tartalmaz játékokat vagy kulcsokat. .&lt;br /&gt;&lt;br /&gt;Mielőtt hozzákezdenél, kérjük, válaszd ki a <![CDATA[<b>prod.keys</b>]]> fájl helyét a készülék tárhelyén&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Tudj meg többet</a>]]></string>
+ <string name="emulation_notification_channel_name">Emuláció aktív</string>
+ <string name="emulation_notification_channel_description">Állandó értesítést jelenít meg, amíg az emuláció fut.</string>
+ <string name="emulation_notification_running">A yuzu fut</string>
+ <string name="notice_notification_channel_name">Megjegyzések és hibák</string>
+ <string name="notice_notification_channel_description">Értesítések megjelenítése, ha valami rosszul sül el.</string>
+ <string name="notification_permission_not_granted">Nincs engedély az értesítés megjelenítéséhez!</string>
+
+ <!-- Setup strings -->
+ <string name="welcome">Üdvözöljük!</string>
+ <string name="welcome_description">Ismerkedj meg a &lt;b>yuzu&lt;/b> beállításával és ugorj bele az emulációba.</string>
+ <string name="get_started">Vágjunk bele</string>
+ <string name="keys">Kulcsok</string>
+ <string name="keys_description">Válaszd ki a(z) &lt;b>prod.keys&lt;/b> fájlodat az alábbi gombbal.</string>
+ <string name="select_keys">Kulcsok kiválasztása</string>
+ <string name="games">Játékok</string>
+ <string name="games_description">
+Válaszd ki a(z) &lt;b>Games&lt;/b> mappát az alábbi gombbal.</string>
+ <string name="done">Kész</string>
+ <string name="done_description">Minden kész.\nJó szórakozást!</string>
+ <string name="text_continue">Folytatás</string>
+ <string name="next">Következő</string>
+ <string name="back">Vissza</string>
+ <string name="add_games">Játékok hozzáadása</string>
+ <string name="add_games_description">Játékaid mappa kiválasztása</string>
+ <string name="step_complete">Kész!</string>
+
+ <!-- Home strings -->
+ <string name="home_games">Játékok</string>
+ <string name="home_search">Keresés</string>
+ <string name="home_settings">Beállítások</string>
+ <string name="empty_gamelist">Nem található fájl, vagy még nincs kiválasztva könyvtár.</string>
+ <string name="search_and_filter_games">Játékok keresése és szűrése</string>
+ <string name="select_games_folder">Játékmappa kiválasztása</string>
+ <string name="add_games_warning">Kihagyod a játékok mappa kiválasztását?</string>
+ <string name="add_games_warning_description">A játékok nem jelennek meg a Játékok listában, ha egy mappa nincs kijelölve.</string>
+ <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
+ <string name="home_search_games">Játékok keresése</string>
+ <string name="search_settings">Beállítások keresése</string>
+ <string name="games_dir_selected">Játékok könyvtár kiválasztva</string>
+ <string name="install_prod_keys">prod.keys telepítése</string>
+ <string name="install_prod_keys_description">Kiskereskedelmi játékok dekódolásához szükséges</string>
+ <string name="install_prod_keys_warning">Kihagyod a kulcsok hozzáadását?</string>
+ <string name="install_prod_keys_warning_description">A kiskereskedelmi játékok emulálásához érvényes kulcsokra van szükség. Csak a homebrew alkalmazások fognak működni, ha folytatod.</string>
+ <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
+ <string name="notifications">Értesítések</string>
+ <string name="notifications_description">Értesítési engedélyek megadása az alábbi gombbal.</string>
+ <string name="give_permission">Engedély megadása</string>
+ <string name="notification_warning">Kihagyod az értesítési engedély megadását?</string>
+ <string name="notification_warning_description">yuzu nem fog tudni értesíteni a fontos imformációkról</string>
+ <string name="permission_denied">Engedély megtagadva</string>
+ <string name="permission_denied_description">Túl gyakran utasítottad el a hozzáférést, így manuálisan kell jóváhagynod a rendszer beállításokban.</string>
+ <string name="about">A programról</string>
+ <string name="about_description">Build verzió, készítők, és még több</string>
+ <string name="warning_help">Segítség</string>
+ <string name="warning_skip">Kihagyás</string>
+ <string name="warning_cancel">Mégse</string>
+ <string name="install_amiibo_keys">Amiibo kulcsok telepítése</string>
+ <string name="install_amiibo_keys_description">Amiibo használata szükséges a játékhoz</string>
+ <string name="invalid_keys_file">Érvénytelen titkosítófájlok kiválasztva</string>
+ <string name="install_keys_success">Kulcsok sikeresen telepítve</string>
+ <string name="reading_keys_failure">Hiba történt a titkosítókulcsok olvasása során</string>
+ <string name="install_prod_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .keys kiterjesztéssel rendelkezik, majd próbáld újra.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .bin kiterjesztéssel rendelkezik, majd próbáld újra.</string>
+ <string name="invalid_keys_error">Érvénytelen titkosítókulcsok</string>
+ <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
+ <string name="install_keys_failure_description">A kiválasztott fájl helytelen, vagy sérült. Állíts össze egy új kulcsot.</string>
+ <string name="install_gpu_driver">GPU illesztőprogram telepítése</string>
+ <string name="install_gpu_driver_description">Alternatív illesztőprogramok telepítése az esetlegesen elérhető teljesítmény és pontosság érdekében</string>
+ <string name="advanced_settings">Haladó beállítások</string>
+ <string name="advanced_settings_game">Haladó beállítások: %1$s</string>
+ <string name="settings_description">Emulátorbeállítások konfigurálása</string>
+ <string name="search_recently_played">Nemrég játszva</string>
+ <string name="search_recently_added">Nemrég hozzáadva</string>
+ <string name="search_retail">Kiskereskedelmi</string>
+ <string name="open_user_folder">yuzu mappa megnyitása</string>
+ <string name="open_user_folder_description">yuzu belső fájljainak kezelése</string>
+ <string name="theme_and_color_description">Az alkalmazás megjelenésének módosítása</string>
+ <string name="no_file_manager">Nem található fájlkezelő</string>
+ <string name="notification_no_directory_link">Nem sikerült megnyitni a yuzu könyvtárat</string>
+ <string name="notification_no_directory_link_description">Kérjük, manuálisan keresd meg a felhasználói mappát a fájlkezelő oldalsó paneljével.</string>
+ <string name="manage_save_data">Mentésadatok kezelése</string>
+ <string name="manage_save_data_description">Mentés található. Kérjük, válassz egyet az alábbi opciók közül.</string>
+ <string name="import_export_saves_description">Mentési fájlok importálás vagy exportálása</string>
+ <string name="save_file_imported_success">Sikeresen importálva</string>
+ <string name="save_file_invalid_zip_structure">Érvénytelen mentési könyvtárstruktúra</string>
+ <string name="save_file_invalid_zip_structure_description">Az első almappa neve a játék azonosítója kell, hogy legyen.</string>
+ <string name="import_saves">Importálás</string>
+ <string name="export_saves">Exportálás</string>
+ <string name="install_firmware">Firmware telepítés</string>
+ <string name="install_firmware_description">A firmwarenek ZIP archívumban kell lennie, és szükséges a játékok indításához</string>
+ <string name="firmware_installing">Firmware telepítése</string>
+ <string name="firmware_installed_success">Firmware sikeresen telepítve</string>
+ <string name="firmware_installed_failure">Firmware telepítése sikertelen</string>
+ <string name="firmware_installed_failure_description">Győződj meg róla, hogy a firmware nca fájlok a zip gyökerénél vannak, és próbáld meg újra.</string>
+ <string name="share_log">Hibakereső logok megosztása</string>
+ <string name="share_log_description">A yuzu naplófájl megosztása a problémák elhárításához</string>
+ <string name="share_log_missing">Nem található log fájl</string>
+ <string name="install_game_content">Játéktartalom telepítése</string>
+ <string name="install_game_content_description">Játékfrissítések vagy DLC telepítése</string>
+ <string name="installing_game_content">Tartalom telepítése...</string>
+ <string name="install_game_content_failure">Hiba történt a fájl(ok) NAND-ra telepítése közben</string>
+ <string name="install_game_content_failure_description">Győződj meg róla, hogy a tartalom valós, és a prod.keys fájl telepítve van.</string>
+ <string name="install_game_content_failure_base">Az alapjátékok telepítése nem engedélyezett az esetleges konfliktusok elkerülése érdekében.</string>
+ <string name="install_game_content_failure_file_extension">Csak NSP és XCI tartalom támogatott. Győződj meg róla, hogy a játéktartalom érvényes.</string>
+ <string name="install_game_content_failed_count">%1$d telepítési hiba</string>
+ <string name="install_game_content_success">Játéktartalom sikeresen telepítve</string>
+ <string name="install_game_content_success_install">%1$d sikeresen telepítve</string>
+ <string name="install_game_content_success_overwrite">%1$d sikeresen felülírva</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">Egyéni illesztőprogramok nem támogatottak</string>
+ <string name="custom_driver_not_supported_description">Egyéni illesztőprogram telepítése jelenleg nem támogatott ezen az eszközön.\nNézz vissza később, hátha hozzáadtuk a támogatását!</string>
+ <string name="manage_yuzu_data">yuzu adatok kezelése</string>
+ <string name="manage_yuzu_data_description">Firmware, kulcsok, felhasználói adatok és egyebek importálása/exportálása</string>
+ <string name="share_save_file">Mentési fájl megosztása</string>
+ <string name="export_save_failed">A mentés exportálása sikertelen</string>
+
+ <!-- About screen strings -->
+ <string name="gaia_is_not_real">Gaia nem valódi</string>
+ <string name="copied_to_clipboard">Másolva a vágólapra</string>
+ <string name="about_app_description">Egy nyílt forráskódú Switch emulátor</string>
+ <string name="contributors">Hozzájárulók</string>
+ <string name="contributors_description">\u2764 által készítve a yuzu csapattól</string>
+ <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Projektek, amik nélkül a yuzu nem jöhetett volna létre Androidra</string>
+ <string name="user_data">Felhasználói adatok</string>
+ <string name="user_data_description">Az összes alkalmazásadat importálása/exportálása.\n\nA felhasználói adatok importálásakor az összes meglévő felhasználói adat törlődik!</string>
+ <string name="exporting_user_data">Felhasználói adatok exportálása...</string>
+ <string name="importing_user_data">Felhasználói adatok importálása...</string>
+ <string name="import_user_data">Felhasználói adatok importálása</string>
+ <string name="invalid_yuzu_backup">Érvénytelen yuzu biztonsági másolat</string>
+ <string name="user_data_export_success">Felhasználói adatok sikeresen exportálva</string>
+ <string name="user_data_import_success">Felhasználói adatok sikeresen importálva</string>
+ <string name="user_data_export_cancelled">Exportálás megszakítva</string>
+ <string name="user_data_import_failed_description">Ellenőrizd, hogy a felhasználói adatok mappái a zip mappa gyökerében vannak, és tartalmaznak egy konfig fájlt a config/config.ini címen, majd próbáld meg újra.</string>
+ <string name="support_link">https://discord.gg/u77vRWY</string>
+ <string name="website_link">https://yuzu-emu.org/</string>
+ <string name="github_link">https://github.com/yuzu-emu</string>
+
+ <!-- Early access upgrade strings -->
+ <string name="early_access">Korai hozzáférés</string>
+ <string name="get_early_access">Szerezz korai hozzáférést</string>
+ <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
+ <string name="get_early_access_description">Legújabb funkciók, korai hozzáférés a frissítésekhez, és sok más</string>
+ <string name="early_access_benefits">Korai hozzáférés előnyei</string>
+ <string name="cutting_edge_features">Legújabb funkciók</string>
+ <string name="early_access_updates">Korai hozzáférés a frissítésekhez</string>
+ <string name="no_manual_installation">Automatikus telepítések</string>
+ <string name="prioritized_support">Priorizált támogatás</string>
+ <string name="our_eternal_gratitude">Valamint az örök hálánk</string>
+ <string name="are_you_interested">Érdekel a dolog?</string>
+
+ <!-- General settings strings -->
+ <string name="frame_limit_enable">Sebességkorlát</string>
+ <string name="frame_limit_enable_description">Korlátozza az emuláció sebességét a normál sebesség adott százalékára.</string>
+ <string name="frame_limit_slider">Sebességkorlát százaléka</string>
+ <string name="frame_limit_slider_description">Az emuláció sebességét határozza meg. 100% a normál sebesség. A magasabb értékek növelik, az alacsonyabbak csökkentik a sebességkorlátot.</string>
+ <string name="cpu_accuracy">CPU pontosság</string>
+ <string name="value_with_units">%1$s%2$s</string>
+
+ <!-- System settings strings -->
+ <string name="use_docked_mode">Dokkolt mód</string>
+ <string name="use_docked_mode_description">Növeli a felbontást, de csökkenti a teljesítményt. Kikapcsolás esetén a Kézi mód van használatban, ami kisebb felbontást, de nagyobb teljesítményt eredményez.</string>
+ <string name="emulated_region">Emulált régió</string>
+ <string name="emulated_language">Emulált nyelv</string>
+ <string name="select_rtc_date">Válassz RTC dátumot</string>
+ <string name="select_rtc_time">Válassz RTC időt</string>
+ <string name="use_custom_rtc">Egyéni RTC</string>
+ <string name="use_custom_rtc_description">Megadhatsz egy valós idejű órát, amely eltér a rendszer által használt órától.</string>
+ <string name="set_custom_rtc">Egyéni RTC beállítása</string>
+
+ <!-- Graphics settings strings -->
+ <string name="renderer_accuracy">Pontosság szintje</string>
+ <string name="renderer_resolution">Felbontás (Kézi/Dockolt)</string>
+ <string name="renderer_vsync">VSync mód</string>
+ <string name="renderer_screen_layout">Orientáció</string>
+ <string name="renderer_aspect_ratio">Képarány</string>
+ <string name="renderer_scaling_filter">Ablakhoz alkalmazkodó szűrő</string>
+ <string name="renderer_anti_aliasing">Élsimítási módszer</string>
+ <string name="renderer_force_max_clock">Maximum órajel kényszerítése (csak Adreno)</string>
+ <string name="renderer_force_max_clock_description">Kényszeríti a GPU-t a lehető legnagyobb órajelen működésre (a hőmérséklet korlátozások továbbra is érvényben maradnak).</string>
+ <string name="renderer_asynchronous_shaders">Aszinkron árnyékolók használata</string>
+ <string name="renderer_asynchronous_shaders_description">Aszinkron módon fordítja az árnyékolókat, ami csökkenti az akadozást, de hibákat okozhat.</string>
+ <string name="renderer_reactive_flushing">Reaktív ürítés használata</string>
+ <string name="renderer_reactive_flushing_description">Javítja a renderelési pontosságot néhány játékban a teljesítmény rovására.</string>
+ <string name="use_disk_shader_cache">Lemez árnyékoló gyorsítótár</string>
+ <string name="use_disk_shader_cache_description">Csökkenti az akadásokat azáltal, hogy helyileg tárolja és tölti be a generált árnyékolókat.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">CPU hibakeresés</string>
+ <string name="cpu_debug_mode_description">Lassú hibakereső módba állítja a CPU-t.</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Grafikai hibakeresés</string>
+ <string name="renderer_debug_description">Lassú hibakeresési módba állítja a grafikus API-t .</string>
+ <!-- Audio settings strings -->
+ <string name="audio_output_engine">Kimeneti rendszer</string>
+ <string name="audio_volume">Hangerő</string>
+ <string name="audio_volume_description">Hangkimenet hangerejének megadása</string>
+
+ <!-- Miscellaneous -->
+ <string name="slider_default">Alapértelmezett</string>
+ <string name="ini_saved">Beállítások elmentve</string>
+ <string name="gameid_saved">Beállítások elmentve a következőhöz: %1$s</string>
+ <string name="error_saving">Mentési hiba%1$s .ini: %2$s</string>
+ <string name="unimplemented_menu">Nem implementált menü</string>
+ <string name="loading">Betöltés...</string>
+ <string name="shutting_down">Leállítás...</string>
+ <string name="reset_setting_confirmation">Szeretnéd visszaállítani a beállítások az alapértelmezett értékekre?</string>
+ <string name="reset_to_default">Alaphelyzetbe állítás</string>
+ <string name="reset_all_settings">Alaphelyzetbe állítod a beállításokat?</string>
+ <string name="reset_all_settings_description">Minden haladó beállítás vissza lesz állítva az alapértelmezett konfigurációra. Ez a művelet nem vonható vissza.</string>
+ <string name="settings_reset">Beállítások alaphelyzetbe állítva</string>
+ <string name="close">Bezárás</string>
+ <string name="learn_more">Tudj meg többet</string>
+ <string name="auto">Automatikus</string>
+ <string name="submit">Küldés</string>
+ <string name="string_null">Nulla</string>
+ <string name="string_import">Importálás</string>
+ <string name="export">Exportálás</string>
+ <string name="export_failed">Exportálás sikertelen</string>
+ <string name="import_failed">Importálás sikertelen</string>
+ <string name="cancelling">Megszakítás</string>
+
+ <!-- GPU driver installation -->
+ <string name="select_gpu_driver">Válassz GPU illesztőprogramot</string>
+ <string name="select_gpu_driver_title">Szeretnéd lecserélni a jelenlegi GPU illesztőprogramot?</string>
+ <string name="select_gpu_driver_install">Telepítés</string>
+ <string name="select_gpu_driver_default">Alapértelmezett</string>
+ <string name="select_gpu_driver_use_default">Alapértelmezett GPU illesztőprogram használata</string>
+ <string name="select_gpu_driver_error">Érvénytelen driver kiválasztva, a rendszer alapértelmezett lesz használva!</string>
+ <string name="system_gpu_driver">Rendszer GPU illesztőprogram</string>
+ <string name="installing_driver">Illesztőprogram telepítése...</string>
+
+ <!-- Preferences Screen -->
+ <string name="preferences_settings">Beállítások</string>
+ <string name="preferences_general">Általános</string>
+ <string name="preferences_system">Rendszer</string>
+ <string name="preferences_graphics">Grafika</string>
+ <string name="preferences_audio">Hang</string>
+ <string name="preferences_theme">Téma és színek</string>
+ <string name="preferences_debug">Hibakeresés</string>
+
+ <!-- ROM loading errors -->
+ <string name="loader_error_encrypted">ROM titkosítva</string>
+ <string name="loader_error_encrypted_keys_description"><![CDATA[Győződj meg róla, hogy a <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> fájl telepítve van, hogy a játékok visszafejthetők legyenek.]]></string>
+ <string name="loader_error_video_core">Hiba lépett fel a videómag inicializása során</string>
+ <string name="loader_error_video_core_description">Ezt általában egy nem kompatibilis GPU illesztő okozza. Egyéni GPU illesztőprogram telepítése megoldhatja a problémát.</string>
+ <string name="loader_error_invalid_format">Nem sikerült betölteni a ROM-ot</string>
+ <string name="loader_error_file_not_found">ROM fájl nem létezik</string>
+
+ <!-- Emulation Menu -->
+ <string name="emulation_exit">Emuláció bezárása</string>
+ <string name="emulation_done">Kész</string>
+ <string name="emulation_fps_counter">FPS számláló</string>
+ <string name="emulation_toggle_controls">Irányítás átkapcsolása</string>
+ <string name="emulation_dpad_slide">D-pad csúsztatása</string>
+ <string name="emulation_haptics">Érintés haptikája</string>
+ <string name="emulation_show_overlay">Átfedés mutatása</string>
+ <string name="emulation_toggle_all">Össze átkapcsolása</string>
+ <string name="emulation_control_adjust">Átfedés testreszabása</string>
+ <string name="emulation_control_scale">Skálázás</string>
+ <string name="emulation_control_opacity">Átlátszóság</string>
+ <string name="emulation_touch_overlay_reset">Átfedés visszaállítása</string>
+ <string name="emulation_touch_overlay_edit">Átfedés módosítása</string>
+ <string name="emulation_pause">Emuláció szünetelése</string>
+ <string name="emulation_unpause">Emuláció folytatása</string>
+ <string name="emulation_input_overlay">Átfedés beállításai</string>
+
+ <string name="load_settings">Beállítások betöltése...</string>
+
+ <!-- Software keyboard -->
+ <string name="software_keyboard">Szoftver billenytűzet</string>
+
+ <!-- Errors and warnings -->
+ <string name="abort_button">Megszakítás</string>
+ <string name="continue_button">Folytatás</string>
+ <string name="system_archive_not_found">Nem található rendszerarchívum</string>
+ <string name="system_archive_not_found_message">%s hiányzik. Kérjük, mentsd ki a rendszerarchívumaidat.\nAz emuláció folytatása összeomlásokhoz és hibákhoz vezethet.</string>
+ <string name="system_archive_general">Egy rendszerarchívum</string>
+ <string name="save_load_error">Mentési/betöltési hiba</string>
+ <string name="fatal_error">Végzetes hiba</string>
+ <string name="fatal_error_message">Végzetes hiba történt. Ellenőrizd a logot a részletekért.\nAz emuláció folytatása összeomlást és hibákat eredményzhet.</string>
+ <string name="performance_warning">Ennek a beállításnak a kikapcsolása jelentős mértékben csökkenti a teljesítményt! A legjobb élmény érdekében javasolt a beállítás bekapcsolva tartása.</string>
+ <string name="device_memory_inadequate">Eszköz RAM: %1$s\nAjánlott: %2$s</string>
+ <string name="memory_formatted">%1$s %2$s</string>
+ <string name="no_game_present">Nincs indítható játék!</string>
+
+ <!-- Region Names -->
+ <string name="region_japan">Japán</string>
+ <string name="region_usa">USA</string>
+ <string name="region_europe">Európa</string>
+ <string name="region_australia">Ausztrália</string>
+ <string name="region_china">Kína</string>
+ <string name="region_korea">Korea</string>
+ <string name="region_taiwan">Tajvan</string>
+
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Bájt</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
+
+ <!-- Renderer APIs -->
+ <string name="renderer_vulkan">Vulkan</string>
+ <string name="renderer_none">Nincs</string>
+
+ <!-- Renderer Accuracy -->
+ <string name="renderer_accuracy_normal">Normál</string>
+ <string name="renderer_accuracy_high">Magas</string>
+ <string name="renderer_accuracy_extreme">Extrém (Lassú)</string>
+
+ <!-- Resolutions -->
+ <string name="resolution_half">0.5X (360p/540p)</string>
+ <string name="resolution_three_quarter">0.75X (540p/810p)</string>
+ <string name="resolution_one">1X (720p/1080p)</string>
+ <string name="resolution_two">2X (1440p/2160p) (Lassú)</string>
+ <string name="resolution_three">3X (2160p/3240p) (Lassú)</string>
+ <string name="resolution_four">4X (2880p/4320p) (Lassú)</string>
+
+ <!-- Renderer VSync -->
+ <string name="renderer_vsync_immediate">Azonnali (Ki)</string>
+ <string name="renderer_vsync_mailbox">Postaláda</string>
+ <string name="renderer_vsync_fifo">FIFO (Be)</string>
+ <string name="renderer_vsync_fifo_relaxed">FIFO Relaxált</string>
+
+ <!-- Scaling Filters -->
+ <string name="scaling_filter_nearest_neighbor">Legközelebbi szomszéd</string>
+ <string name="scaling_filter_bilinear">Bilineáris</string>
+ <string name="scaling_filter_bicubic">Bikubikus</string>
+ <string name="scaling_filter_gaussian">Gauss-féle</string>
+ <string name="scaling_filter_scale_force">ScaleForce</string>
+ <string name="scaling_filter_fsr">AMD FidelityFX™ Super Resolution</string>
+
+ <!-- Anti-Aliasing -->
+ <string name="anti_aliasing_none">Nincs</string>
+ <string name="anti_aliasing_fxaa">FXAA</string>
+ <string name="anti_aliasing_smaa">SMAA</string>
+
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">Fekvő</string>
+ <string name="screen_layout_portrait">Álló</string>
+ <string name="screen_layout_auto">Automatikus</string>
+
+ <!-- Aspect Ratios -->
+ <string name="ratio_default">Alapértelmezett (16:9)</string>
+ <string name="ratio_force_four_three">4:3 kényszerítése</string>
+ <string name="ratio_force_twenty_one_nine">21:9 kényszerítése</string>
+ <string name="ratio_force_sixteen_ten">16:10 kényszerítése</string>
+ <string name="ratio_stretch">Ablakhoz nyújtás</string>
+
+ <!-- CPU Accuracy -->
+ <string name="cpu_accuracy_accurate">Pontos</string>
+ <string name="cpu_accuracy_unsafe">Nem biztonságos</string>
+ <string name="cpu_accuracy_paranoid">Paranoid (Lassú)</string>
+
+ <!-- Gamepad Buttons -->
+ <string name="gamepad_d_pad">D-pad</string>
+ <string name="gamepad_left_stick">Bal kar</string>
+ <string name="gamepad_right_stick">Jobb kar</string>
+ <string name="gamepad_home">Home</string>
+ <string name="gamepad_screenshot">Képernyőmentés</string>
+
+ <!-- Disk shader cache -->
+ <string name="preparing_shaders">Árnyékolók előkészítése</string>
+ <string name="building_shaders">Árnyékolók létrehozása</string>
+
+ <!-- Theme options -->
+ <string name="change_app_theme">Alkalmazás témájának módosítása</string>
+ <string name="theme_default">Alapértelmezett</string>
+ <!-- Theme Modes -->
+ <string name="change_theme_mode">Téma váltása</string>
+ <string name="theme_mode_follow_system">Rendszerbeállítások használata</string>
+ <string name="theme_mode_light">Világos</string>
+ <string name="theme_mode_dark">Sötét</string>
+
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
+ <!-- Black backgrounds theme -->
+ <string name="use_black_backgrounds">Fekete háttér</string>
+ <string name="use_black_backgrounds_description">Sötét téma használatakor fekete háttér használata.</string>
+
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Kép a képben</string>
+ <string name="picture_in_picture_description">Ablak minimalizálása, amikor háttérbe kerül</string>
+ <string name="pause">Szünet</string>
+ <string name="play">Lejátszás</string>
+ <string name="mute">Némítás</string>
+ <string name="unmute">Némítás feloldása</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Licenszek</string>
+ <string name="license_fidelityfx_fsr_description">Magas minőségű felskálázás az AMD-től</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml
index 09c9345b0..5afebb4c4 100644
--- a/src/android/app/src/main/res/values-it/strings.xml
+++ b/src/android/app/src/main/res/values-it/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">Questo software permette di giocare ai giochi della console Nintendo Switch. Nessun gioco o chiave è inclusa.&lt;br /&gt;&lt;br /&gt;Prima di iniziare, perfavore individua il file <![CDATA[<b>prod.keys </b>]]> nella memoria del tuo dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Scopri di più</a>]]></string>
<string name="emulation_notification_channel_name">L\'emulatore è attivo</string>
@@ -13,9 +13,9 @@
<string name="welcome">Benvenuto!</string>
<string name="welcome_description">Scopri come configurare &lt;b>yuzu&lt;/b> e passare all\'emulazione.</string>
<string name="get_started">Iniziare</string>
- <string name="keys">Pulsanti</string>
+ <string name="keys">Chiavi</string>
<string name="keys_description">Seleziona il tuo file &lt;b>prod.keys&lt;/b> con il pulsante in basso.</string>
- <string name="select_keys">Selezione Pulsanti</string>
+ <string name="select_keys">Seleziona le chiavi</string>
<string name="games">Giochi</string>
<string name="games_description">Seleziona la cartella &lt;b>Games&lt;/b> con il pulsante in basso.</string>
<string name="done">Fatto</string>
@@ -25,6 +25,7 @@
<string name="back">Indietro</string>
<string name="add_games">Aggiungi giochi</string>
<string name="add_games_description">Seleziona la cartella dei giochi</string>
+ <string name="step_complete">Completato!</string>
<!-- Home strings -->
<string name="home_games">Giochi</string>
@@ -38,6 +39,7 @@
<string name="add_games_warning_description">I giochi non saranno mostrati nella lista dei giochi se una cartella non è selezionata.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">Cerca giochi</string>
+ <string name="search_settings">Cerca impostazione</string>
<string name="games_dir_selected">Cartella dei giochi selezionata</string>
<string name="install_prod_keys">Installa prod.keys</string>
<string name="install_prod_keys_description">Necessario per decrittografare i giochi</string>
@@ -61,15 +63,18 @@
<string name="invalid_keys_file">Selezionate chiavi non valide</string>
<string name="install_keys_success">Chiavi installate correttamente</string>
<string name="reading_keys_failure">Errore durante la lettura delle chiavi di crittografia</string>
+ <string name="install_prod_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .keys e prova di nuovo.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .bin e prova di nuovo</string>
<string name="invalid_keys_error">Chiavi di crittografia non valide</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">Il file selezionato è incorretto o corrotto. Per favore riesegui il dump delle tue chiavi.</string>
<string name="install_gpu_driver">Installa i driver GPU</string>
<string name="install_gpu_driver_description">Installa driver alternativi per potenziali prestazioni migliori o accuratezza.</string>
<string name="advanced_settings">Impostazioni avanzate</string>
+ <string name="advanced_settings_game">Impostazioni Avanzate: %1$s</string>
<string name="settings_description">Configura le impostazioni dell\'emulatore</string>
- <string name="search_recently_played">Giocato recentemente</string>
- <string name="search_recently_added">Aggiunto recentemente</string>
+ <string name="search_recently_played">Giocati recentemente</string>
+ <string name="search_recently_added">Aggiunti recentemente</string>
<string name="search_retail">Rivenditore</string>
<string name="search_homebrew">Homebrew</string>
<string name="open_user_folder">Apri la cartella di yuzu</string>
@@ -86,6 +91,33 @@
<string name="save_file_invalid_zip_structure_description">La prima sotto cartella <b>deve</b> chiamarsi come l\'ID del titolo del gioco.</string>
<string name="import_saves">Importa</string>
<string name="export_saves">Esporta</string>
+ <string name="install_firmware">Installa firmware</string>
+ <string name="install_firmware_description">Il firmware deve essere in un archivio ZIP ed è necessario per avviare alcuni giochi</string>
+ <string name="firmware_installing">Installando il firmware</string>
+ <string name="firmware_installed_success">Firmware installato con successo</string>
+ <string name="firmware_installed_failure">L\'installazione del firmware è fallita</string>
+ <string name="firmware_installed_failure_description">Accertati che i file .nca del firmware siano contenuti direttamente nella radice dello .zip e riprova.</string>
+ <string name="share_log">Condividi log di debug</string>
+ <string name="share_log_description">Condividi i log di yuzu per ricevere supporto</string>
+ <string name="share_log_missing">Nessun file di log trovato</string>
+ <string name="install_game_content">Installa contenuti di gioco</string>
+ <string name="install_game_content_description">Installa aggiornamenti o DLC</string>
+ <string name="installing_game_content">Installazione dei contenuti...</string>
+ <string name="install_game_content_failure">Errore durante l\'installazione del contenuto in NAND.</string>
+ <string name="install_game_content_failure_description">Accertati che i contenuti da installare siano validi e che le prod.keys siano presenti.</string>
+ <string name="install_game_content_failure_base">Installare i giochi base in NAND non è permesso, perché potrebbe causare dei conflitti con altri tipi di contenuti(Aggiornamenti e DLC)</string>
+ <string name="install_game_content_failure_file_extension">Solo i tipi NSP e XCI sono supportati. Verifica che i contenuti di gioco siano validi.</string>
+ <string name="install_game_content_failed_count">Errori di installazione: %1$d</string>
+ <string name="install_game_content_success">Contenuto/i di gioco installato/i con successo.</string>
+ <string name="install_game_content_success_install">%1$dinstallato con successo.</string>
+ <string name="install_game_content_success_overwrite">%1$dsovrascritto con successo</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">I driver personalizzati non sono supportati.</string>
+ <string name="custom_driver_not_supported_description">I driver personalizzati non sono attualmente supportati su questo dispositivo.\n Ricontrolla in futuro.</string>
+ <string name="manage_yuzu_data">Gestisci i dati di Yuzu</string>
+ <string name="manage_yuzu_data_description">Importa/Esporta il firmware, le keys, i dati utente, e altro!</string>
+ <string name="share_save_file">Condividi i tuoi dati di salvataggio</string>
+ <string name="export_save_failed">Errore durante l\'esportazione del salvataggio</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia non è reale</string>
@@ -94,7 +126,18 @@
<string name="contributors">Collaboratori</string>
<string name="contributors_description">Realizzato con \u2764 dal team yuzu</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Progetti che rendono yuzu per Android possibile</string>
<string name="build">Compilazione</string>
+ <string name="user_data">Dati Utente</string>
+ <string name="user_data_description">Importa/Esporta tutti i dati dell\'applicazione.\n\nDurante l\'importazione dei Dati Utente, quelli già esistenti verranno ELIMINATI.</string>
+ <string name="exporting_user_data">Esportazione dei Dati Utente...</string>
+ <string name="importing_user_data">Importazione dei Dati Utente...</string>
+ <string name="import_user_data">Importa i Dati Utente</string>
+ <string name="invalid_yuzu_backup">Backup di Yuzu Invalido</string>
+ <string name="user_data_export_success">Dati Utente esportati con successo</string>
+ <string name="user_data_import_success">Dati Utente importati con successo.</string>
+ <string name="user_data_export_cancelled">Esportazione annullata</string>
+ <string name="user_data_import_failed_description">Assicurati che la cartella dei Dati dell\'utente stiano nella radice del file.zip e che sia presente una cartella config in config/config.ini, poi, riprova.</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
<string name="are_you_interested">Sei interessato?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Abilita il limite di velocità</string>
- <string name="frame_limit_enable_description">Quando abilitato, la velocità di emulazione verrà limitata a una specifica percentuale della velocità normale.</string>
+ <string name="frame_limit_enable">Limita velocità</string>
+ <string name="frame_limit_enable_description">Limita la velocità dell\'emulazione a una specifica percentuale della velocità normale.</string>
<string name="frame_limit_slider">Limite velocità percentuale</string>
- <string name="frame_limit_slider_description">Specifica la percentuale del limite della velocità di emulazione. Con quella preimpostata al 100% l\'emulazione verrà limitata alla velocità normale. Valori più alti o bassi aumenteranno o diminuiranno il limite di velocità.</string>
+ <string name="frame_limit_slider_description">Specifica la percentuale per limitare la velocità di emulazione. 100% è la velocità normale. Valori maggiori o minori aumenteranno o diminuiranno il limite di velocità</string>
<string name="cpu_accuracy">Accuratezza della CPU</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
- <string name="use_docked_mode">Modalità docked</string>
- <string name="use_docked_mode_description">Emula in modalità docked, questo aumenta la risoluzione a spese delle performance.</string>
+ <string name="use_docked_mode">Modalità Docked</string>
+ <string name="use_docked_mode_description">Aumenta la risoluzione, diminuendo le performance. La modalità portatile è usata quando disabilitato, diminuendo la risoluzione e aumentando le performance.</string>
<string name="emulated_region">Regione emulata</string>
<string name="emulated_language">Lingua emulata</string>
- <string name="select_rtc_date">Seleziona la data dall\'orologio in tempo reale</string>
- <string name="select_rtc_time">Seleziona il tempo dall\'orologio in tempo reale</string>
- <string name="use_custom_rtc">Abilità l\'orologio in tempo reale personalizzato</string>
- <string name="use_custom_rtc_description">Questa impostazione ti permette di impostare un orologio in tempo reale personalizzato separato da quello del tuo sistema corrente.</string>
- <string name="set_custom_rtc">Imposta l\'orologio in tempo reale personalizzato</string>
+ <string name="select_rtc_date">Imposta la data </string>
+ <string name="select_rtc_time">Imposta l\'ora, i minuti e i secondi.</string>
+ <string name="use_custom_rtc">RTC Personalizzato</string>
+ <string name="use_custom_rtc_description">Ti permette di impostare un orologio in tempo reale personalizzato, completamente separato da quello di sistema.</string>
+ <string name="set_custom_rtc">Imposta un orologio in tempo reale personalizzato</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Livello di accuratezza</string>
- <string name="renderer_resolution">Risoluzione</string>
+ <string name="renderer_resolution">Risoluzione (Portatile/Docked)</string>
<string name="renderer_vsync">Modalità VSync</string>
- <string name="renderer_aspect_ratio">Rapporto d\'aspetto</string>
- <string name="renderer_scaling_filter">Filtro di adattamento alla finestra</string>
+ <string name="renderer_screen_layout">Orientamento</string>
+ <string name="renderer_aspect_ratio">Rapporto d\'aspetto: </string>
+ <string name="renderer_scaling_filter">Filtro adattivo della finestra </string>
<string name="renderer_anti_aliasing">Metodo di anti-aliasing</string>
<string name="renderer_force_max_clock">Forza clock massimi (solo Adreno)</string>
<string name="renderer_force_max_clock_description">Forza la GPU a girare col massimo clock possibile (i vincoli alla temperatura saranno comunque applicati)</string>
<string name="renderer_asynchronous_shaders">Usa shaders asincrone</string>
- <string name="renderer_asynchronous_shaders_description">Compila le shaders asincronamente, questo riduce lo shutter ma potrebbe introdurre dei glitch. </string>
- <string name="renderer_debug">Abilità il debug grafico</string>
- <string name="renderer_debug_description">Quando l\'opzione è selezionata, l\'API grafica entra in una modalità di debug più lenta</string>
- <string name="use_disk_shader_cache">Usa cache shader su disco</string>
- <string name="use_disk_shader_cache_description">Riduce lo stuttering salvando e caricando le shader generate sul disco.</string>
+ <string name="renderer_asynchronous_shaders_description">Compila le shader in modo asincrone, riducendo lo stutter. Può causare glitch grafici.</string>
+ <string name="renderer_reactive_flushing">Abilita il Reactive Flushing</string>
+ <string name="renderer_reactive_flushing_description">Migliora l\'accuratezza della grafica in alcuni giochi, al costo delle performance.</string>
+ <string name="use_disk_shader_cache">Usa la cache delle shader</string>
+ <string name="use_disk_shader_cache_description">Riduce lo stuttering caricando le shader già compilate all\'avvio.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">Debug della CPU</string>
+ <string name="cpu_debug_mode_description">Imposta la CPU in modalità Debug (Più lento)</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Debug GPU</string>
+ <string name="renderer_debug_description">Imposta l\'API grafica in uno stato dedicato al Debugging. Impatta di molto sulle performance.</string>
+ <string name="fastmem">Fastmem</string>
<!-- Audio settings strings -->
+ <string name="audio_output_engine">Motore di Output</string>
<string name="audio_volume">Volume</string>
<string name="audio_volume_description">Specifica il volume dell\'audio in uscita.</string>
@@ -157,14 +212,24 @@
<string name="ini_saved">Impostazioni salvate</string>
<string name="gameid_saved">Impostazioni salvate per %1$s</string>
<string name="error_saving">Errore nel salvare %1$s.ini %2$s</string>
+ <string name="unimplemented_menu">Menu non implementato</string>
<string name="loading">Caricamento…</string>
+ <string name="shutting_down">Spegnimento...</string>
<string name="reset_setting_confirmation">Vuoi ripristinare queste impostazioni al loro valore originale?</string>
<string name="reset_to_default">Riportare alle impostazioni originali</string>
<string name="reset_all_settings">Resettare tutte le impostazioni?</string>
- <string name="reset_all_settings_description">Tutte le Impostazioni Avanzate saranno ripristinate a quelle originali. Questa operazione non è reversibile</string>
+ <string name="reset_all_settings_description">Le impostazione avanzate verranno completamente reimpostate. Questa operazione è IRREVERSIBILE.</string>
<string name="settings_reset">Reimposta le impostazioni</string>
<string name="close">Chiudi</string>
<string name="learn_more">Per saperne di più</string>
+ <string name="auto">Automatico</string>
+ <string name="submit">Invia</string>
+ <string name="string_null">Nullo</string>
+ <string name="string_import">Importa</string>
+ <string name="export">Esporta</string>
+ <string name="export_failed">Esportazione Fallita</string>
+ <string name="import_failed">Importazione Fallita</string>
+ <string name="cancelling">Cancellazione</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Seleziona il driver della GPU</string>
@@ -172,6 +237,7 @@
<string name="select_gpu_driver_install">Installa</string>
<string name="select_gpu_driver_default">Predefinito</string>
<string name="select_gpu_driver_use_default">Utilizza il driver predefinito della GPU.</string>
+ <string name="select_gpu_driver_error">Il driver selezionato è invalido, è in utilizzo quello predefinito di sistema!</string>
<string name="system_gpu_driver">Driver GPU del sistema</string>
<string name="installing_driver">Installando i driver...</string>
@@ -182,10 +248,11 @@
<string name="preferences_graphics">Grafica</string>
<string name="preferences_audio">Audio</string>
<string name="preferences_theme">Tema e colori</string>
+ <string name="preferences_debug">Debug</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">La tua ROM è criptata</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Per favore segui la guida per eseguire il dump della <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">cartuccia di gioco</a> o i <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">titoli installati</a>.]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[Segui la nostra guida per fare il <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">dump delle tue cartucce di gioco</a>oppure <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">dei titoli già installati</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Per favore assicurati che il file <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> sia installato in modo che i giochi possano essere decrittati.]]></string>
<string name="loader_error_video_core">È stato riscontrato un errore nell\'inizializzazione del core video</string>
<string name="loader_error_video_core_description">Questo è causato solitamente dal driver incompatibile di una GPU. L\'installazione di driver GPU personalizzati potrebbe risolvere questo problema.</string>
@@ -193,28 +260,28 @@
<string name="loader_error_file_not_found">Il file della ROM non esiste</string>
<!-- Emulation Menu -->
- <string name="emulation_exit">Uscire dall\'emulazione</string>
+ <string name="emulation_exit">Arresta emulazione</string>
<string name="emulation_done">Fatto</string>
- <string name="emulation_fps_counter">Contatore degli FPS</string>
+ <string name="emulation_fps_counter">Contatore FPS</string>
<string name="emulation_toggle_controls">Controlli a interruttore</string>
<string name="emulation_rel_stick_center">Centro relativo degli Stick</string>
- <string name="emulation_dpad_slide">Slittamento del Pad Direzionale</string>
- <string name="emulation_haptics">Aptico</string>
- <string name="emulation_show_overlay">Mostra Overlay</string>
- <string name="emulation_toggle_all">Attiva/disattiva tutto</string>
- <string name="emulation_control_adjust">Aggiusta Overlay</string>
+ <string name="emulation_dpad_slide">DPad A Scorrimento</string>
+ <string name="emulation_haptics">Feedback Aptico</string>
+ <string name="emulation_show_overlay">Mostra l\'Overlay</string>
+ <string name="emulation_toggle_all">Attiva/Disattiva tutto</string>
+ <string name="emulation_control_adjust">Modifica l\'Overlay</string>
<string name="emulation_control_scale">Scala</string>
<string name="emulation_control_opacity">Opacità</string>
- <string name="emulation_touch_overlay_reset">Reimposta Overlay</string>
- <string name="emulation_touch_overlay_edit">Modifica Overlay</string>
- <string name="emulation_pause">Metti in pausa l\'emulazione</string>
- <string name="emulation_unpause">Riprendi Emulazione</string>
- <string name="emulation_input_overlay">Impostazioni Overlay</string>
+ <string name="emulation_touch_overlay_reset">Reimposta l\'Overlay</string>
+ <string name="emulation_touch_overlay_edit">Modifica l\'Overlay</string>
+ <string name="emulation_pause">Sospendi l\'emulazione</string>
+ <string name="emulation_unpause">Riprendi l\'emulazione</string>
+ <string name="emulation_input_overlay">Opzioni overlay</string>
- <string name="load_settings">Caricamento delle impostazioni...</string>
+ <string name="load_settings">Carico le impostazioni...</string>
<!-- Software keyboard -->
- <string name="software_keyboard">Tastiera software</string>
+ <string name="software_keyboard">Tastiera Software</string>
<!-- Errors and warnings -->
<string name="abort_button">Interrompi</string>
@@ -226,6 +293,9 @@
<string name="fatal_error">Errore Fatale</string>
<string name="fatal_error_message">Un errore fatale è accaduto. Controlla i log per i dettagli.\nContinuare ad emulare potrebbe portare bug o causare crash.</string>
<string name="performance_warning">Disattivare questa impostazione può ridurre significativamente le performance di emulazione! Per una migliore esperienza, è consigliato lasciare questa impostazione attivata.</string>
+ <string name="device_memory_inadequate">RAM Totale:%1$s\nRaccomandati: %2$s</string>
+ <string name="memory_formatted">%1$s%2$s</string>
+ <string name="no_game_present">Non è presente alcun gioco avviabile.</string>
<!-- Region Names -->
<string name="region_japan">Giappone</string>
@@ -236,7 +306,14 @@
<string name="region_korea">Corea</string>
<string name="region_taiwan">Taiwan</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">Kb</string>
+ <string name="memory_megabyte">Mb</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">Tb</string>
+ <string name="memory_petabyte">Pb</string>
+ <string name="memory_exabyte">Eb</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
@@ -274,12 +351,17 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">Layout Orizzontale</string>
+ <string name="screen_layout_portrait">Layout Verticale</string>
+ <string name="screen_layout_auto">Automatico</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Predefinito (16:9)</string>
<string name="ratio_force_four_three">Forza 4:3</string>
<string name="ratio_force_twenty_one_nine">Forza 21:9</string>
<string name="ratio_force_sixteen_ten">Forza 16:10</string>
- <string name="ratio_stretch">Allunga a finestra</string>
+ <string name="ratio_stretch">Adatta alla finestra</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">Accurata</string>
@@ -287,9 +369,9 @@
<string name="cpu_accuracy_paranoid">Paranoico (Lento)</string>
<!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">D-Pad</string>
- <string name="gamepad_left_stick">Levetta sinistra</string>
- <string name="gamepad_right_stick">Levetta destra</string>
+ <string name="gamepad_d_pad">D-pad</string>
+ <string name="gamepad_left_stick">Analogico sinistro</string>
+ <string name="gamepad_right_stick">Analogico destro</string>
<string name="gamepad_home">Home</string>
<string name="gamepad_screenshot">Screenshot</string>
@@ -298,7 +380,7 @@
<string name="building_shaders">Costruendo gli shaders</string>
<!-- Theme options -->
- <string name="change_app_theme">Cambia il tema dell\'app</string>
+ <string name="change_app_theme">Cambia tema dell\'app</string>
<string name="theme_default">Predefinito</string>
<string name="theme_material_you">Material You</string>
@@ -308,8 +390,22 @@
<string name="theme_mode_light">Chiaro</string>
<string name="theme_mode_dark">Scuro</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Usa sfondi neri</string>
+ <string name="use_black_backgrounds">Sfondi neri</string>
<string name="use_black_backgrounds_description">Quando utilizzi il tema scuro, applica sfondi neri.</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Picture in Picture</string>
+ <string name="picture_in_picture_description">Minimizza la finestra quando viene impostata in background</string>
+ <string name="pause">Pausa</string>
+ <string name="play">Gioca</string>
+ <string name="mute">Silenzia</string>
+ <string name="unmute">Riattiva</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Licenze</string>
+ <string name="license_fidelityfx_fsr_description">Upscaling di alta qualità da parte di AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml
index a0ea78bef..3be4e7d26 100644
--- a/src/android/app/src/main/res/values-ja/strings.xml
+++ b/src/android/app/src/main/res/values-ja/strings.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
- <string name="app_disclaimer">このソフトウェアは、Nintendo Switch用のゲームを実行します。 ゲームソフトやキーは含まれません。&lt;br /&gt;&lt;br /&gt;事前に、 <![CDATA[<b> prod.keys </b>]]> ファイルをデバイスのストレージに配置しておいてください。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">詳細</a>]]></string>
+ <string name="app_disclaimer">このソフトウェアでは、Nintendo Switchのゲームを実行できます。 ゲームソフトやキーは含まれません。&lt;br /&gt;&lt;br /&gt;事前に、 <![CDATA[<b> prod.keys </b>]]> ファイルをストレージに配置しておいてください。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">詳細</a>]]></string>
<string name="emulation_notification_channel_name">エミュレーションが有効です</string>
<string name="emulation_notification_channel_description">エミュレーションの実行中に常設通知を表示します。</string>
<string name="emulation_notification_running">yuzu は実行中です</string>
- <string name="notice_notification_channel_description">問題が発生したときに通知を表示します。</string>
+ <string name="notice_notification_channel_name">通知とエラー</string>
+ <string name="notice_notification_channel_description">問題の発生時に通知を表示します。</string>
<string name="notification_permission_not_granted">通知が許可されていません!</string>
<!-- Setup strings -->
@@ -16,7 +17,7 @@
<string name="keys_description">下のボタンから &lt;b>prod.keys&lt;/b> ファイルを選択してください。</string>
<string name="select_keys">キーを選択</string>
<string name="games">ゲーム</string>
- <string name="games_description">下のボタンから&lt;b>ゲーム&lt;/b>があるフォルダを選択してください。</string>
+ <string name="games_description">下のボタンから&lt;b>ゲーム&lt;/b>のあるフォルダを選択してください。</string>
<string name="done">完了</string>
<string name="done_description">準備が完了しました。\nゲームをお楽しみください!</string>
<string name="text_continue">続行</string>
@@ -24,48 +25,53 @@
<string name="back">戻る</string>
<string name="add_games">ゲームを追加</string>
<string name="add_games_description">ゲームフォルダを選択</string>
+ <string name="step_complete">完了!</string>
<!-- Home strings -->
<string name="home_games">ゲーム</string>
<string name="home_search">検索</string>
<string name="home_settings">設定</string>
- <string name="empty_gamelist">ファイルが見つからないか、ゲームディレクトリがまだ選択されていません。</string>
+ <string name="empty_gamelist">ファイルが存在しないかゲームフォルダが選択されていません。</string>
<string name="search_and_filter_games">ゲームの検索と絞り込み</string>
- <string name="select_games_folder">ゲームフォルダを選択</string>
- <string name="select_games_folder_description">yuzu がゲームリストに追加できるようにします</string>
+ <string name="select_games_folder">ゲームフォルダ</string>
+ <string name="select_games_folder_description">ゲームをyuzuのゲームリストに追加します</string>
<string name="add_games_warning">ゲームフォルダの選択をスキップしますか?</string>
- <string name="add_games_warning_description">フォルダを選択しない場合、ゲームはゲームリストに表示されません。</string>
+ <string name="add_games_warning_description">フォルダを選択しないと、ゲームがリストに表示されません。</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">ゲームを検索</string>
- <string name="games_dir_selected">ゲームディレクトリが選択されました</string>
- <string name="install_prod_keys">prod.keys をインストール</string>
- <string name="install_prod_keys_description">ゲームの復号化に必要</string>
+ <string name="search_settings">検索設定</string>
+ <string name="games_dir_selected">フォルダを選択しました</string>
+ <string name="install_prod_keys">prod.keys</string>
+ <string name="install_prod_keys_description">製品版ゲームの復号化に必要です</string>
<string name="install_prod_keys_warning">キーの追加をスキップしますか?</string>
<string name="install_prod_keys_warning_description">製品版ゲームのエミュレーションには、有効なキーが必要です。続行すると自作アプリしか機能しません。</string>
<string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
<string name="notifications">通知</string>
- <string name="notifications_description">下のボタンで通知の権限を許可してください。</string>
+ <string name="notifications_description">下のボタンで通知を許可してください。</string>
<string name="give_permission">許可</string>
<string name="notification_warning">通知の許可をスキップしますか?</string>
<string name="notification_warning_description">yuzuは重要なお知らせを通知できません。</string>
<string name="permission_denied">権限が拒否されました</string>
- <string name="permission_denied_description">この権限を複数回拒否したため、システム設定で手動で許可する必要があります。</string>
+ <string name="permission_denied_description">この権限を複数回拒否したため、設定から手動で許可する必要があります。</string>
<string name="about">情報</string>
<string name="about_description">ビルドバージョン、クレジットなど</string>
<string name="warning_help">ヘルプ</string>
<string name="warning_skip">スキップ</string>
<string name="warning_cancel">キャンセル</string>
- <string name="install_amiibo_keys">Amiibo キーをインストール</string>
- <string name="install_amiibo_keys_description">ゲーム内での Amiibo の使用に必要</string>
- <string name="invalid_keys_file">無効なキーファイルが選択されました</string>
+ <string name="install_amiibo_keys">Amiibo</string>
+ <string name="install_amiibo_keys_description">ゲーム内での Amiibo の使用に必要です</string>
+ <string name="invalid_keys_file">無効なキーファイルです</string>
<string name="install_keys_success">正常にインストールされました</string>
- <string name="reading_keys_failure">暗号化キーの読み取りエラー</string>
- <string name="invalid_keys_error">暗号化キーが無効です</string>
+ <string name="reading_keys_failure">暗号化キーの読み込み失敗</string>
+ <string name="install_prod_keys_failure_extension_description">キーの拡張子が.keysであることを確認し、再度お試しください。</string>
+ <string name="install_amiibo_keys_failure_extension_description">キーの拡張子が.binであることを確認し、再度お試しください。</string>
+ <string name="invalid_keys_error">暗号化キーが無効</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
- <string name="install_keys_failure_description">選択されたファイルが不正または破損しています。キーを再ダンプしてください。</string>
- <string name="install_gpu_driver">GPUドライバーをインストール</string>
+ <string name="install_keys_failure_description">ファイルが間違っているか破損しています。キーを再ダンプしてください。</string>
+ <string name="install_gpu_driver">GPUドライバー</string>
<string name="install_gpu_driver_description">代替ドライバーをインストールしてパフォーマンスや精度を向上させます</string>
<string name="advanced_settings">高度な設定</string>
+ <string name="advanced_settings_game">高度な設定: %1$s</string>
<string name="settings_description">エミュレーターの設定を構成します</string>
<string name="search_recently_played">最近プレイした</string>
<string name="search_recently_added">最近追加された</string>
@@ -77,15 +83,34 @@
<string name="no_file_manager">ファイルマネージャーが見つかりませんでした</string>
<string name="notification_no_directory_link">yuzuのディレクトリを開けません</string>
<string name="notification_no_directory_link_description">ファイルマネージャのサイドパネルでユーザーフォルダを手動で探してください。</string>
- <string name="manage_save_data">セーブデータを管理</string>
- <string name="manage_save_data_description">セーブデータが見つかりました。以下のオプションから選択してください。</string>
+ <string name="manage_save_data">セーブデータ</string>
+ <string name="manage_save_data_description">セーブデータが見つかりました。操作を選択してください。</string>
<string name="import_export_saves_description">セーブファイルをインポート/エクスポート</string>
<string name="save_file_imported_success">インポートが完了しました</string>
- <string name="save_file_invalid_zip_structure">セーブデータのディレクトリ構造が無効です</string>
+ <string name="save_file_invalid_zip_structure">セーブデータのディレクトリ構造が無効</string>
<string name="save_file_invalid_zip_structure_description">最初のサブフォルダ名は、ゲームのタイトルIDである必要があります。</string>
<string name="import_saves">インポート</string>
<string name="export_saves">エクスポート</string>
-
+ <string name="install_firmware">ファームウェア</string>
+ <string name="install_firmware_description">ファームウェアはZIPアーカイブである必要があり、一部のゲームを起動するのに必要です</string>
+ <string name="firmware_installing">ファームウェアをインストール中</string>
+ <string name="firmware_installed_success">インストールが完了しました</string>
+ <string name="firmware_installed_failure">インストール失敗</string>
+ <string name="share_log">デバッグログ</string>
+ <string name="share_log_description">yuzuのログファイルを共有して問題をデバッグします</string>
+ <string name="share_log_missing">ログが見つかりません</string>
+ <string name="install_game_content">追加コンテンツ</string>
+ <string name="install_game_content_description">更新データやDLCをインストールします</string>
+ <string name="installing_game_content">コンテンツをインストール中...</string>
+ <string name="install_game_content_failure_file_extension">NSPとXCI形式のコンテンツのみサポートされています。ゲームコンテンツが有効なものであるかご確認ください。</string>
+ <string name="install_game_content_failed_count">%1$d のインストールエラー</string>
+ <string name="install_game_content_success">ゲームコンテンツのインストールに成功しました</string>
+ <string name="install_game_content_success_install">%1$d のインストールに成功しました</string>
+ <string name="install_game_content_success_overwrite">%1$d の上書きに成功しました</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">カスタムドライバはサポートされていません</string>
+ <string name="manage_yuzu_data">yuzu データを管理</string>
+ <string name="share_save_file">セーブファイルを共有</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">ガイアは実在しない</string>
<string name="copied_to_clipboard">クリップボードにコピーしました</string>
@@ -93,7 +118,15 @@
<string name="contributors">貢献者</string>
<string name="contributors_description">yuzuチームの\u2764で作られた</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">yuzu for Androidの作成を可能にしたプロジェクト</string>
<string name="build">ビルド</string>
+ <string name="user_data">ユーザデータ</string>
+ <string name="exporting_user_data">ユーザデータをエクスポート中...</string>
+ <string name="importing_user_data">ユーザデータをインポート中...</string>
+ <string name="import_user_data">ユーザデータをインポート</string>
+ <string name="user_data_export_success">ユーザデータのエクスポートに成功しました</string>
+ <string name="user_data_import_success">ユーザデータのインポートに成功しました</string>
+ <string name="user_data_export_cancelled">エクスポートをキャンセルしました</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -105,72 +138,91 @@
<string name="get_early_access_description">最先端の機能、アップデートの早期アクセスなど</string>
<string name="early_access_benefits">早期アクセスのメリット</string>
<string name="cutting_edge_features">最先端の機能</string>
- <string name="early_access_updates">アップデートの早期アクセス</string>
+ <string name="early_access_updates">アップデートへの早期アクセス</string>
<string name="no_manual_installation">手動インストールが不要</string>
- <string name="prioritized_support">優先的なサポート</string>
+ <string name="prioritized_support">優先サポート</string>
<string name="helping_game_preservation">ゲームの保存に貢献</string>
- <string name="our_eternal_gratitude">私たちの永遠の感謝</string>
+ <string name="our_eternal_gratitude">私たちから永遠の感謝</string>
<string name="are_you_interested">興味がありますか?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">速度制限を有効化</string>
- <string name="frame_limit_enable_description">有効にすると、エミュレーション速度が任意の割合に制限されます。</string>
- <string name="frame_limit_slider">エミュレーション速度の制限</string>
- <string name="frame_limit_slider_description">エミュレーション速度を制限する割合を指定します。デフォルトの100%では、エミュレーションは通常の速度に制限されます。値が高いまたは低いほど、速度制限が増加または減少します。</string>
+ <string name="frame_limit_enable">エミュレーション速度を制限</string>
+ <string name="frame_limit_enable_description">エミュレーション速度を指定した割合に制限します。</string>
+ <string name="frame_limit_slider">エミュレーション速度</string>
+ <string name="frame_limit_slider_description">エミュレーション速度を制限するパーセンテージを指定します。100%は通常速度です。値の増減で速度も増減します。</string>
<string name="cpu_accuracy">CPU精度</string>
-
<!-- System settings strings -->
<string name="use_docked_mode">TVモード</string>
- <string name="use_docked_mode_description">TVモードでエミュレートします。パフォーマンスが犠牲になりますが、解像度が向上します。</string>
+ <string name="use_docked_mode_description">高解像度、低パフォーマンス。無効時には携帯モードが使用されます(低解像度、高パフォーマンス)。</string>
<string name="emulated_region">地域</string>
<string name="emulated_language">言語</string>
<string name="select_rtc_date">RTCの日付を選択</string>
<string name="select_rtc_time">RTCの時刻を選択</string>
- <string name="use_custom_rtc">カスタムRTC</string>
- <string name="use_custom_rtc_description">現在のシステム時間とは別にカスタムのリアルタイムクロックを設定できます。</string>
+ <string name="use_custom_rtc">カスタム RTC</string>
+ <string name="use_custom_rtc_description">現在のシステム時間とは別に、任意のリアルタイムクロックを設定できます。</string>
<string name="set_custom_rtc">カスタムRTCを設定</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">精度</string>
- <string name="renderer_resolution">解像度</string>
+ <string name="renderer_resolution">解像度(携帯モード/TVモード)</string>
<string name="renderer_vsync">垂直同期モード</string>
+ <string name="renderer_screen_layout">画面の向き</string>
<string name="renderer_aspect_ratio">アスペクト比</string>
<string name="renderer_scaling_filter">ウィンドウ適応フィルター</string>
<string name="renderer_anti_aliasing">アンチエイリアス方式</string>
<string name="renderer_force_max_clock">最大クロックを強制 (Adrenoのみ)</string>
- <string name="renderer_force_max_clock_description">GPUを可能な限り最大クロックで動作させます (過熱制限は引き続き適用されます)。</string>
+ <string name="renderer_force_max_clock_description">GPUを最大限可能な周波数で動作させます (過熱制限は引き続き適用されます)。</string>
<string name="renderer_asynchronous_shaders">非同期シェーダー</string>
<string name="renderer_asynchronous_shaders_description">シェーダーを非同期でコンパイルします。コマ落ちが軽減されますが、不具合が発生する可能性があります。</string>
+ <string name="renderer_reactive_flushing">即時書き込み</string>
+ <string name="renderer_reactive_flushing_description">一部のゲームにおいて、パフォーマンスを犠牲にしながらも、レンダリング精度を向上させます。</string>
+ <string name="use_disk_shader_cache">ディスクシェーダーキャッシュ</string>
+ <string name="use_disk_shader_cache_description">生成したシェーダーを端末に保存して読み込み、コマ落ちを軽減します。</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">CPU デバッギング</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
<string name="renderer_debug">グラフィックデバッグ</string>
- <string name="renderer_debug_description">オンにすると、グラフィックAPI は低速のデバッグモードに入ります。</string>
- <string name="use_disk_shader_cache">シェーダーキャッシュを使用</string>
- <string name="use_disk_shader_cache_description">生成したシェーダーをディスクに保存して読み込むことで、コマ落ちを軽減します。</string>
+ <string name="renderer_debug_description">グラフィックAPIを低速デバッグモードに設定します。</string>
+ <string name="fastmem">Fastmem</string>
<!-- Audio settings strings -->
+ <string name="audio_output_engine">出力エンジン</string>
<string name="audio_volume">音量</string>
<string name="audio_volume_description">オーディオ出力の音量を指定します</string>
<!-- Miscellaneous -->
<string name="slider_default">デフォルト</string>
<string name="ini_saved">設定を保存しました</string>
- <string name="gameid_saved">%1$sの設定を保存しました</string>
+ <string name="gameid_saved">%1$s の設定を保存しました</string>
<string name="error_saving">%1$s.ini の保存エラー: %2$s</string>
+ <string name="unimplemented_menu">未実装のメニュー</string>
<string name="loading">読み込み中…</string>
+ <string name="shutting_down">終了中...</string>
<string name="reset_setting_confirmation">この設定を初期値にリセットしますか?</string>
<string name="reset_to_default">初期設定に戻す</string>
<string name="reset_all_settings">すべての設定をリセットしますか?</string>
- <string name="reset_all_settings_description">すべての詳細設定が初期設定に戻されます。この操作は元に戻せません。</string>
+ <string name="reset_all_settings_description">すべての詳細設定が初期値に戻されます。この操作は元に戻せません。</string>
<string name="settings_reset">設定をリセットしました</string>
<string name="close">閉じる</string>
<string name="learn_more">詳細情報</string>
+ <string name="auto">自動</string>
+ <string name="submit">送信</string>
+ <string name="string_import">インポート</string>
+ <string name="export">エクスポート</string>
+ <string name="export_failed">エクスポート失敗</string>
+ <string name="import_failed">インポート失敗</string>
+ <string name="cancelling">キャンセル中</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">GPUドライバを選択</string>
- <string name="select_gpu_driver_title">現在のGPUドライバーを置き換えますか?</string>
+ <string name="select_gpu_driver_title">現在のGPUドライバを置き換えますか?</string>
<string name="select_gpu_driver_install">インストール</string>
<string name="select_gpu_driver_default">デフォルト</string>
- <string name="select_gpu_driver_use_default">デフォルトのGPUドライバーを使用します</string>
+ <string name="select_gpu_driver_use_default">デフォルトのドライバを使用します</string>
+ <string name="select_gpu_driver_error">選択されたドライバが無効、システムのデフォルトを使用します!</string>
<string name="system_gpu_driver">システムのGPUドライバ</string>
<string name="installing_driver">インストール中…</string>
@@ -181,33 +233,34 @@
<string name="preferences_graphics">グラフィック</string>
<string name="preferences_audio">サウンド</string>
<string name="preferences_theme">テーマと色</string>
+ <string name="preferences_debug">デバッグ</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">ROMが暗号化されています</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">ゲームカートリッジ</a>や<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">インストール済みのタイトル</a>を再度ダンプするためのガイドに従ってください。]]></string>
- <string name="loader_error_encrypted_keys_description"><![CDATA[ゲームを復号化するために <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> ファイルがインストールされていることを確認してください。]]></string>
+ <string name="loader_error_encrypted_keys_description"><![CDATA[ゲームの復号化に必要な <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> ファイルがインストールされていることを確認してください。]]></string>
<string name="loader_error_video_core">ビデオコアの初期化中にエラーが発生しました</string>
<string name="loader_error_video_core_description">これは通常、互換性のないGPUドライバーが原因で発生します。 カスタムGPUドライバーをインストールすると、問題が解決する可能性があります。</string>
<string name="loader_error_invalid_format">ROMの読み込みに失敗しました</string>
<string name="loader_error_file_not_found">ROMファイルが存在しません</string>
<!-- Emulation Menu -->
- <string name="emulation_exit">エミュレーションを終了</string>
+ <string name="emulation_exit">終了</string>
<string name="emulation_done">完了</string>
<string name="emulation_fps_counter">FPSカウンター</string>
- <string name="emulation_toggle_controls">コントロールを切り替え</string>
- <string name="emulation_dpad_slide">十字キーのスライド操作</string>
- <string name="emulation_haptics">振動</string>
- <string name="emulation_show_overlay">オーバーレイを表示</string>
- <string name="emulation_toggle_all">すべて選択</string>
- <string name="emulation_control_adjust">オーバーレイを調整</string>
+ <string name="emulation_toggle_controls">ボタンの表示設定</string>
+ <string name="emulation_rel_stick_center">スティックを固定しない</string>
+ <string name="emulation_dpad_slide">十字キーをスライド操作</string>
+ <string name="emulation_haptics">タッチ振動</string>
+ <string name="emulation_show_overlay">ボタンを表示</string>
+ <string name="emulation_toggle_all">すべて切替</string>
+ <string name="emulation_control_adjust">見た目を調整</string>
<string name="emulation_control_scale">大きさ</string>
<string name="emulation_control_opacity">不透明度</string>
<string name="emulation_touch_overlay_reset">リセット</string>
- <string name="emulation_touch_overlay_edit">オーバーレイを編集</string>
- <string name="emulation_pause">エミュレーションを一時停止</string>
- <string name="emulation_unpause">エミュレーションを再開</string>
- <string name="emulation_input_overlay">オーバーレイオプション</string>
+ <string name="emulation_touch_overlay_edit">位置を編集</string>
+ <string name="emulation_pause">一時停止</string>
+ <string name="emulation_unpause">再開</string>
+ <string name="emulation_input_overlay">表示オプション</string>
<string name="load_settings">設定をロード中…</string>
@@ -220,10 +273,13 @@
<string name="system_archive_not_found">システムアーカイブが見つかりません</string>
<string name="system_archive_not_found_message">%s が見つかりません。システムアーカイブをダンプしてください。\nエミュレーションを続行すると、クラッシュやバグが発生する可能性があります。</string>
<string name="system_archive_general">システムアーカイブ</string>
- <string name="save_load_error">セーブ/ロード エラー</string>
+ <string name="save_load_error">セーブ/ロードエラー</string>
<string name="fatal_error">致命的なエラー</string>
<string name="fatal_error_message">致命的なエラーが発生しました。詳細はログを確認してください。\nエミュレーションを続行するとクラッシュやバグが発生する可能性があります。</string>
- <string name="performance_warning">この設定をオフにすると、エミュレーションのパフォーマンスが著しく低下します!最高の体験を得るためには、この設定を有効にしておくことをお勧めします。</string>
+ <string name="performance_warning">この設定をオフにすると、エミュレーションのパフォーマンスが著しく低下します!最高の体験を得るためには、この設定を有効にしておくことを推奨します。</string>
+ <string name="device_memory_inadequate">デバイス RAM: %1$s\n推奨: %2$s</string>
+ <string name="memory_formatted">%1$s %2$s</string>
+ <string name="no_game_present">起動できるゲームがありません!</string>
<!-- Region Names -->
<string name="region_japan">日本</string>
@@ -234,7 +290,14 @@
<string name="region_korea">韓国</string>
<string name="region_taiwan">台湾</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
@@ -242,7 +305,7 @@
<!-- Renderer Accuracy -->
<string name="renderer_accuracy_normal">標準</string>
- <string name="renderer_accuracy_high">高い</string>
+ <string name="renderer_accuracy_high">高</string>
<string name="renderer_accuracy_extreme">最高 (低速)</string>
<!-- Resolutions -->
@@ -272,12 +335,17 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">横長</string>
+ <string name="screen_layout_portrait">縦長</string>
+ <string name="screen_layout_auto">自動</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">デフォルト (16:9)</string>
<string name="ratio_force_four_three">強制 4:3</string>
<string name="ratio_force_twenty_one_nine">強制 21:9</string>
<string name="ratio_force_sixteen_ten">強制 16:10</string>
- <string name="ratio_stretch">ウィンドウに合わせる</string>
+ <string name="ratio_stretch">画面に合わせる</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">正確</string>
@@ -289,7 +357,7 @@
<string name="gamepad_left_stick">Lスティック</string>
<string name="gamepad_right_stick">Rスティック</string>
<string name="gamepad_home">HOMEボタン</string>
- <string name="gamepad_screenshot">スクリーンショット</string>
+ <string name="gamepad_screenshot">キャプチャーボタン</string>
<!-- Disk shader cache -->
<string name="preparing_shaders">シェーダーを準備しています</string>
@@ -306,8 +374,22 @@
<string name="theme_mode_light">ライト</string>
<string name="theme_mode_dark">ダーク</string>
- <!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">黒色の背景を使用</string>
- <string name="use_black_backgrounds_description">ダークテーマの使用時は、黒色の背景を有効にしてください。</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
-</resources>
+ <!-- Black backgrounds theme -->
+ <string name="use_black_backgrounds">完全な黒を使用</string>
+ <string name="use_black_backgrounds_description">ダークテーマの背景色に黒が適用されます。</string>
+
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">ピクチャーインピクチャー</string>
+ <string name="picture_in_picture_description">バックグラウンド時にウインドウを最小化する</string>
+ <string name="pause">中断</string>
+ <string name="play">プレイ</string>
+ <string name="mute">消音</string>
+ <string name="unmute">消音解除</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">ライセンス</string>
+ <string name="license_fidelityfx_fsr_description">AMDの高品質アップスケーリング</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml
index 214f95706..1b9160a23 100644
--- a/src/android/app/src/main/res/values-ko/strings.xml
+++ b/src/android/app/src/main/res/values-ko/strings.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
- <string name="app_disclaimer">이 소프트웨어는 닌텐도 스위치 게임 콘솔용 게임을 실행합니다. 게임 타이틀이나 keys는 포함되어 있지 않습니다.&lt;br /&gt;&lt;br /&gt;시작하기 전에 장치 저장소에서 <![CDATA[<b> prod.keys </b>]]> 파일을 찾아주세요.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">자세히 알아보기</a>]]></string>
+ <string name="app_disclaimer">이 소프트웨어는 Nintendo Switch 게임을 실행합니다. 게임 타이틀이나 키는 포함되어 있지 않습니다.&lt;br /&gt;&lt;br /&gt;시작하기 전에 장치 저장소에서 <![CDATA[<b> prod.keys </b>]]> 파일을 찾아주세요.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">자세히 알아보기</a>]]></string>
<string name="emulation_notification_channel_name">에뮬레이션이 활성화됨</string>
- <string name="emulation_notification_channel_description">에뮬레이션이 실행 중일 때 영구 알림을 표시합니다.</string>
+ <string name="emulation_notification_channel_description">에뮬레이션이 실행 중일 때 지속적으로 알림을 표시합니다.</string>
<string name="emulation_notification_running">yuzu가 실행 중입니다.</string>
<string name="notice_notification_channel_name">알림 및 오류</string>
<string name="notice_notification_channel_description">문제가 발생하면 알림을 표시합니다.</string>
@@ -11,26 +11,25 @@
<!-- Setup strings -->
<string name="welcome">환영합니다!</string>
- <string name="welcome_description">&lt;b>yuzu&lt;/b> 를 설정하고 에뮬레이션으로 이동하는 방법을 알아보세요.</string>
+ <string name="welcome_description">&lt;b>yuzu&lt;/b>를 설정하고 에뮬레이션을 시작하세요.</string>
<string name="get_started">시작하기</string>
- <string name="keys">Keys</string>
- <string name="keys_description">아래 버튼을 사용하여 &lt;b>prod.keys&lt;/b> 파일을 선택합니다.</string>
- <string name="select_keys">keys 선택</string>
+ <string name="keys">키 설정</string>
+ <string name="keys_description">아래 버튼으로 &lt;b>prod.keys&lt;/b> 파일을 선택합니다.</string>
+ <string name="select_keys">키 선택</string>
<string name="games">게임</string>
<string name="games_description">아래 버튼으로 &lt;b>게임&lt;/b> 폴더를 선택합니다.</string>
<string name="done">완료</string>
- <string name="done_description">모든 준비가 완료되었습니다.\n게임을 즐기세요!</string>
+ <string name="done_description">모두 준비되었습니다.\n게임을 즐기세요!</string>
<string name="text_continue">계속</string>
<string name="next">다음</string>
- <string name="back">뒤로</string>
+ <string name="back">이전</string>
<string name="add_games">게임 추가</string>
<string name="add_games_description">게임 폴더 선택</string>
-
<!-- Home strings -->
<string name="home_games">게임</string>
<string name="home_search">검색</string>
<string name="home_settings">설정</string>
- <string name="empty_gamelist">파일을 찾을 수 없거나 아직 게임 디렉토리를 선택하지 않았습니다.</string>
+ <string name="empty_gamelist">파일을 찾을 수 없거나 아직 게임 디렉터리를 선택하지 않았습니다.</string>
<string name="search_and_filter_games">게임 검색 및 필터링</string>
<string name="select_games_folder">게임 폴더 선택</string>
<string name="select_games_folder_description">yuzu가 게임 목록을 채울 수 있도록 허용</string>
@@ -38,140 +37,160 @@
<string name="add_games_warning_description">폴더를 선택하지 않으면 게임 목록에 게임이 표시되지 않습니다.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">게임 검색</string>
- <string name="games_dir_selected">게임 디렉터리 선택</string>
+ <string name="games_dir_selected">게임 디렉터리를 설정했습니다.</string>
<string name="install_prod_keys">prod.keys 설치</string>
- <string name="install_prod_keys_description">판매용 게임 암호 해독에 요구</string>
- <string name="install_prod_keys_warning">keys 추가를 건너뛰겠습니까?</string>
- <string name="install_prod_keys_warning_description">정품 게임을 에뮬레이트하려면 유효한 keys가 필요합니다. 계속하면 자체 제작 앱만 작동합니다.</string>
+ <string name="install_prod_keys_description">패키지 게임 암호 해독에 필요</string>
+ <string name="install_prod_keys_warning">키 추가를 건너뛰겠습니까?</string>
+ <string name="install_prod_keys_warning_description">패키지 게임을 에뮬레이트하려면 유효한 키 값이 필요합니다. 이 단계를 건너뛰면 홈브류 게임만 실행할 수 있습니다.</string>
<string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
<string name="notifications">알림</string>
<string name="notifications_description">아래 버튼으로 알림 권한을 부여합니다.</string>
- <string name="give_permission">권한 부여</string>
- <string name="notification_warning">알림 권한 부여를 건너뛰겠습니까?</string>
- <string name="notification_warning_description">yuzu는 중요한 정보를 알려드리지 않습니다.</string>
+ <string name="give_permission">알림 켜기</string>
+ <string name="notification_warning">알림을 끄겠습니까?</string>
+ <string name="notification_warning_description">yuzu가 중요한 정보를 알려드리지 않습니다.</string>
<string name="permission_denied">권한 거부됨</string>
- <string name="permission_denied_description">이 권한을 너무 많이 거부했으므로 이제 시스템 설정에서 수동으로 권한을 부여해야 합니다.</string>
+ <string name="permission_denied_description">권한 허용을 너무 많이 거부하여 시스템 설정에서 수동으로 권한을 부여해야 합니다.</string>
<string name="about">정보</string>
<string name="about_description">빌드 버전, 크레딧 등</string>
<string name="warning_help">도움말</string>
<string name="warning_skip">건너뛰기</string>
<string name="warning_cancel">취소</string>
- <string name="install_amiibo_keys">Amiibo keys 설치</string>
- <string name="install_amiibo_keys_description">게임에서 아미보 사용 시 필요</string>
- <string name="invalid_keys_file">잘못된 keys 파일 선택</string>
- <string name="install_keys_success">keys가 성공적으로 설치됨</string>
- <string name="reading_keys_failure">암호화 keys 읽기 오류</string>
- <string name="invalid_keys_error">잘못된 암호화 keys</string>
+ <string name="install_amiibo_keys">amiibo 키 설치</string>
+ <string name="install_amiibo_keys_description">게임에서 amiibo 사용 시 필요</string>
+ <string name="invalid_keys_file">잘못된 키 파일이 선택됨</string>
+ <string name="install_keys_success">키 값을 설치했습니다.</string>
+ <string name="reading_keys_failure">암호화 키 읽기 오류</string>
+ <string name="install_prod_keys_failure_extension_description">키 파일의 확장자가 .keys인지 확인하고 다시 시도하세요.</string>
+ <string name="install_amiibo_keys_failure_extension_description">키 파일의 확장자가 .bin인지 확인하고 다시 시도하세요.</string>
+ <string name="invalid_keys_error">암호화 키가 올바르지 않음</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
- <string name="install_keys_failure_description">선택한 파일이 잘못되었거나 손상되었습니다. keys를 다시 덤프하세요.</string>
+ <string name="install_keys_failure_description">선택한 파일이 잘못되었거나 손상되었습니다. 키를 다시 덤프하세요.</string>
<string name="install_gpu_driver">GPU 드라이버 설치</string>
<string name="install_gpu_driver_description">잠재적으로 더 나은 성능 또는 정확성을 위해 대체 드라이버를 설치하세요.</string>
<string name="advanced_settings">고급 설정</string>
<string name="settings_description">에뮬레이터 설정 구성</string>
- <string name="search_recently_played">최근 플레이한 게임</string>
- <string name="search_recently_added">최근 추가한 게임</string>
- <string name="search_retail">판매용</string>
+ <string name="search_recently_played">최근 플레이</string>
+ <string name="search_recently_added">최근 추가</string>
+ <string name="search_retail">패키지</string>
<string name="search_homebrew">홈브류</string>
<string name="open_user_folder">yuzu 폴더 열기</string>
<string name="open_user_folder_description">yuzu의 내부 파일 관리</string>
- <string name="theme_and_color_description">앱 모양 수정</string>
+ <string name="theme_and_color_description">앱 디자인 편집</string>
<string name="no_file_manager">파일 관리자를 찾을 수 없음</string>
- <string name="notification_no_directory_link">yuzu 디렉토리를 열 수 없음</string>
+ <string name="notification_no_directory_link">yuzu 디렉터리를 열 수 없음</string>
<string name="notification_no_directory_link_description">파일 관리자의 사이드 패널에서 사용자 폴더를 수동으로 찾아주세요.</string>
<string name="manage_save_data">저장 데이터 관리</string>
- <string name="manage_save_data_description">데이터를 저장했습니다. 아래에서 옵션을 선택하세요.</string>
+ <string name="manage_save_data_description">저장 데이터를 발견했습니다. 아래에서 옵션을 선택하세요.</string>
<string name="import_export_saves_description">저장 파일 가져오기 또는 내보내기</string>
- <string name="save_file_imported_success">가져오기 성공</string>
- <string name="save_file_invalid_zip_structure">저장 디렉터리 구조가 잘못됨</string>
+ <string name="save_file_imported_success">데이터를 불러왔습니다.</string>
+ <string name="save_file_invalid_zip_structure">올바르지 않은 저장 디렉터리 구조</string>
<string name="save_file_invalid_zip_structure_description">첫 번째 하위 폴더 이름은 게임의 타이틀 ID여야 합니다.</string>
<string name="import_saves">가져오기</string>
<string name="export_saves">내보내기</string>
-
+ <string name="install_firmware">펌웨어 설치</string>
+ <string name="install_firmware_description">펌웨어는 ZIP 파일이며 일부 게임을 부팅하는 데 필요합니다.</string>
+ <string name="firmware_installing">펌웨어 설치</string>
+ <string name="firmware_installed_success">펌웨어를 설치했습니다.</string>
+ <string name="firmware_installed_failure">펌웨어 설치 실패</string>
+ <string name="share_log">디버그 로그 공유</string>
+ <string name="share_log_description">yuzu의 로그 파일을 공유하여 문제 디버깅하기</string>
+ <string name="share_log_missing">로그 파일을 찾을 수 없습니다.</string>
+ <string name="install_game_content">게임 콘텐츠 설치</string>
+ <string name="install_game_content_description">게임 업데이트 또는 DLC 설치</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">가이아는 진짜가 아님</string>
- <string name="copied_to_clipboard">클립보드에 복사</string>
- <string name="about_app_description">오픈 소스 스위치 에뮬레이터</string>
+ <string name="copied_to_clipboard">클립보드에 복사되었습니다.</string>
+ <string name="about_app_description">오픈 소스 Switch 에뮬레이터</string>
<string name="contributors">기여자</string>
<string name="contributors_description">yuzu 팀의 \u2764로 제작</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Android용 yuzu를 가능하게 하는 프로젝트</string>
<string name="build">빌드</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
<!-- Early access upgrade strings -->
- <string name="early_access">미리 체험하기</string>
- <string name="get_early_access">미리 체험하기 신청</string>
+ <string name="early_access">앞서 해보기</string>
+ <string name="get_early_access">앞서 해보기 신청</string>
<string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
- <string name="get_early_access_description">최첨단 기능, 미리 체험하기 업데이트 등</string>
- <string name="early_access_benefits">미리 체험하기 혜택</string>
- <string name="cutting_edge_features">최첨단 기능</string>
- <string name="early_access_updates">미리 체험하기 업데이트</string>
+ <string name="get_early_access_description">최신 기능, 업데이트 미리 체험 등</string>
+ <string name="early_access_benefits">앞서 해보기 혜택</string>
+ <string name="cutting_edge_features">최신 기능</string>
+ <string name="early_access_updates">업데이트 미리 체험</string>
<string name="no_manual_installation">수동 설치 불필요</string>
<string name="prioritized_support">우선 지원</string>
- <string name="helping_game_preservation">게임 보존 도움주기</string>
- <string name="our_eternal_gratitude">영원한 감사의 마음을 전합니다</string>
+ <string name="helping_game_preservation">게임 보존 지원</string>
+ <string name="our_eternal_gratitude">우리의 영원한 감사의 마음</string>
<string name="are_you_interested">관심 있으세요?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">제한 속도 활성화</string>
- <string name="frame_limit_enable_description">활성화하면 에뮬레이션 속도가 정상 속도의 지정된 비율로 제한됩니다.</string>
+ <string name="frame_limit_enable">속도 제한</string>
+ <string name="frame_limit_enable_description">에뮬레이션 속도를 정상 속도의 지정된 비율로 제한합니다.</string>
<string name="frame_limit_slider">속도 제한 비율</string>
- <string name="frame_limit_slider_description">에뮬레이션 속도를 제한할 비율을 지정합니다. 기본값인 100%로 설정하면 에뮬레이션이 정상 속도로 제한됩니다. 값이 높거나 낮으면 속도 제한이 증가하거나 감소합니다.</string>
+ <string name="frame_limit_slider_description">에뮬레이션 속도의 제한 비율을 지정합니다. 100%가 정상 속도입니다. 값이 높거나 낮으면 속도 제한이 증가하거나 감소합니다.</string>
<string name="cpu_accuracy">CPU 정확도</string>
-
<!-- System settings strings -->
- <string name="use_docked_mode">도킹 모드</string>
- <string name="use_docked_mode_description">도킹 모드에서 에뮬레이션하면 성능이 저하되는 대신 해상도가 향상됩니다.</string>
- <string name="emulated_region">에뮬레이트된 지역</string>
- <string name="emulated_language">에뮬레이트된 언어</string>
+ <string name="use_docked_mode">독 모드</string>
+ <string name="use_docked_mode_description">해상도를 높이며 성능이 저하됩니다. 비활성화시 휴대 모드가 사용되며 해상도는 낮아지고 성능은 향상됩니다.</string>
+ <string name="emulated_region">에뮬레이트 지역</string>
+ <string name="emulated_language">에뮬레이트 언어</string>
<string name="select_rtc_date">RTC 날짜 선택</string>
<string name="select_rtc_time">RTC 시간 선택</string>
- <string name="use_custom_rtc">커스텀 RTC 활성화</string>
- <string name="use_custom_rtc_description">이 설정을 사용하면 현재 시스템 시간과 별도로 사용자 지정 실시간 시계를 설정할 수 있음</string>
- <string name="set_custom_rtc">커스텀 RTC 설정</string>
+ <string name="use_custom_rtc">사용자 지정 RTC</string>
+ <string name="use_custom_rtc_description">현재 시스템 시간과 별도로 사용자 지정 실시간 시계를 설정할 수 있습니다.</string>
+ <string name="set_custom_rtc">사용자 지정 RTC 설정</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">정확도 수준</string>
- <string name="renderer_resolution">해상도</string>
+ <string name="renderer_resolution">해상도 (휴대 모드/독 모드)</string>
<string name="renderer_vsync">수직동기화 모드</string>
<string name="renderer_aspect_ratio">화면비</string>
- <string name="renderer_scaling_filter">창 적응 필터</string>
- <string name="renderer_anti_aliasing">안티-에일리어싱 방법</string>
- <string name="renderer_force_max_clock">최대 클럭 강제 설정 (아드레노만 해당)</string>
+ <string name="renderer_scaling_filter">윈도우 적응 필터</string>
+ <string name="renderer_anti_aliasing">안티에일리어싱 방법</string>
+ <string name="renderer_force_max_clock">최대 클럭 강제 설정 (아드레노 전용)</string>
<string name="renderer_force_max_clock_description">GPU가 가능한 최대 클럭으로 실행되도록 강제합니다 (열 제약 조건은 여전히 적용됩니다).</string>
<string name="renderer_asynchronous_shaders">비동기 셰이더 사용</string>
- <string name="renderer_asynchronous_shaders_description">셰이더를 비동기식으로 컴파일하므로 끊김 현상이 줄어들지만 글리치가 발생할 수 있습니다.</string>
- <string name="renderer_debug">그래픽 디버깅 활성화</string>
- <string name="renderer_debug_description">이 옵션을 선택하면 그래픽 API가 느린 디버깅 모드로 전환됩니다.</string>
- <string name="use_disk_shader_cache">디스크 셰이더 캐시 사용</string>
- <string name="use_disk_shader_cache_description">생성된 셰이더를 디스크에 저장하고 불러오기하여 끊김 현상을 줄입니다.</string>
-
- <!-- Audio settings strings -->
+ <string name="renderer_asynchronous_shaders_description">셰이더를 비동기식으로 컴파일하여 끊김 현상을 줄이지만 글리치가 발생할 수 있습니다.</string>
+ <string name="renderer_reactive_flushing">반응형 플러싱 사용</string>
+ <string name="renderer_reactive_flushing_description">일부 게임에서 성능 저하를 감수하고 렌더링 정확도를 향상합니다.</string>
+ <string name="use_disk_shader_cache">디스크 셰이더 캐시</string>
+ <string name="use_disk_shader_cache_description">생성된 셰이더를 로컬에 저장하고 로드하여 끊김 현상을 줄입니다.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">그래픽 디버깅</string>
+ <string name="renderer_debug_description">그래픽 API를 느린 디버깅 모드로 설정합니다.</string>
<string name="audio_volume">볼륨</string>
<string name="audio_volume_description">오디오 출력의 볼륨을 지정합니다.</string>
<!-- Miscellaneous -->
<string name="slider_default">기본값</string>
- <string name="ini_saved">저장된 설정</string>
- <string name="gameid_saved">%1$s를 위해 저장된 설정</string>
- <string name="error_saving">%1$s.ini 저장 중 오류: %2$s</string>
- <string name="loading">불러오기 중...</string>
- <string name="reset_setting_confirmation">이 설정을 기본값으로 되돌리겠습니까?</string>
+ <string name="ini_saved">설정이 저장되었습니다.</string>
+ <string name="gameid_saved">%1$s 전용 설정이 저장되었습니다.</string>
+ <string name="error_saving">%1$s.ini 저장 중 오류 발생: %2$s</string>
+ <string name="loading">불러오는 중...</string>
+ <string name="reset_setting_confirmation">이 설정을 기본값으로 재설정하겠습니까?</string>
<string name="reset_to_default">기본값으로 재설정</string>
<string name="reset_all_settings">모든 설정을 초기화하겠습니까?</string>
- <string name="reset_all_settings_description">모든 고급 설정이 기본 구성으로 재설정됩니다. 이 설정은 되돌릴 수 없습니다.</string>
+ <string name="reset_all_settings_description">모든 고급 설정이 기본 구성으로 재설정됩니다. 이 작업은 되돌릴 수 없습니다.</string>
<string name="settings_reset">설정 초기화</string>
<string name="close">닫기</string>
- <string name="learn_more">자세히 알아보기</string>
-
+ <string name="learn_more">자세히</string>
+ <string name="auto">자동</string>
+ <string name="submit">제출</string>
+ <string name="string_null">Null</string>
+ <string name="string_import">가져오기</string>
+ <string name="export">내보내기</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">GPU 드라이버 선택</string>
- <string name="select_gpu_driver_title">현재 사용 중인 GPU 드라이버를 교체하겠습니까?</string>
+ <string name="select_gpu_driver_title">현재 사용중인 GPU 드라이버를 변경하겠습니까?</string>
<string name="select_gpu_driver_install">설치</string>
<string name="select_gpu_driver_default">기본값</string>
- <string name="select_gpu_driver_use_default">기본 GPU 드라이버 사용</string>
+ <string name="select_gpu_driver_use_default">기본 GPU 드라이버를 사용합니다.</string>
+ <string name="select_gpu_driver_error">잘못된 드라이브가 선택되었습니다. 시스템 기본값을 사용합니다.</string>
<string name="system_gpu_driver">시스템 GPU 드라이버</string>
<string name="installing_driver">드라이버 설치 중...</string>
@@ -182,51 +201,50 @@
<string name="preferences_graphics">그래픽</string>
<string name="preferences_audio">오디오</string>
<string name="preferences_theme">테마 및 색상</string>
+ <string name="preferences_debug">디버그</string>
<!-- ROM loading errors -->
- <string name="loader_error_encrypted">롬이 암호화되었음</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[가이드에 따라 <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">게임 카트리지</a> 또는 <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">설치된 타이틀</a>를 다시 덤프하세요.]]></string>
- <string name="loader_error_encrypted_keys_description"><![CDATA[P게임을 해독할 수 있도록 <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 파일이 설치되어 있는지 확인하세요.]]></string>
+ <string name="loader_error_encrypted">롬 파일이 암호화되어있음</string>
+ <string name="loader_error_encrypted_keys_description"><![CDATA[게임을 해독할 수 있도록 <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 파일이 설치되어 있는지 확인하세요.]]></string>
<string name="loader_error_video_core">비디오 코어를 초기화하는 동안 오류 발생</string>
- <string name="loader_error_video_core_description">이 문제는 일반적으로 호환되지 않는 GPU 드라이버로 인해 발생합니다. 사용자 지정 GPU 드라이버를 설치하면 이 문제가 해결될 수 있습니다.</string>
- <string name="loader_error_invalid_format">롬을 불러올 수 없음</string>
+ <string name="loader_error_video_core_description">일반적으로 이 문제는 호환되지 않는 GPU 드라이버로 인해 발생합니다. 사용자 지정 GPU 드라이버를 설치하면 이 문제가 해결될 수 있습니다.</string>
+ <string name="loader_error_invalid_format">롬 파일을 불러올 수 없음</string>
<string name="loader_error_file_not_found">롬 파일이 존재하지 않음</string>
<!-- Emulation Menu -->
<string name="emulation_exit">에뮬레이션 종료</string>
<string name="emulation_done">완료</string>
- <string name="emulation_fps_counter">FPS 카운터</string>
- <string name="emulation_toggle_controls">토글 제어</string>
- <string name="emulation_rel_stick_center">상대 스틱 센터</string>
- <string name="emulation_dpad_slide">십자패드 슬라이드</string>
- <string name="emulation_haptics">햅틱</string>
- <string name="emulation_show_overlay">오버레이 표시</string>
- <string name="emulation_toggle_all">모두 토글</string>
- <string name="emulation_control_adjust">오버레이 조정</string>
- <string name="emulation_control_scale">스케일</string>
+ <string name="emulation_fps_counter">FPS 표시</string>
+ <string name="emulation_toggle_controls">컨트롤러 선택</string>
+ <string name="emulation_rel_stick_center">스틱의 중심 이동</string>
+ <string name="emulation_dpad_slide">십자키 슬라이드</string>
+ <string name="emulation_haptics">터치 햅틱</string>
+ <string name="emulation_show_overlay">컨트롤러 표시</string>
+ <string name="emulation_toggle_all">모두 선택</string>
+ <string name="emulation_control_adjust">컨트롤러 조정</string>
+ <string name="emulation_control_scale">크기</string>
<string name="emulation_control_opacity">불투명도</string>
- <string name="emulation_touch_overlay_reset">오버레이 재설정</string>
- <string name="emulation_touch_overlay_edit">오버레이 편집</string>
+ <string name="emulation_touch_overlay_reset">컨트롤러 설정 초기화</string>
+ <string name="emulation_touch_overlay_edit">컨트롤러 위치 편집</string>
<string name="emulation_pause">에뮬레이션 일시 중지</string>
<string name="emulation_unpause">에뮬레이션 일시 중지 해제</string>
- <string name="emulation_input_overlay">오버레이 옵션</string>
+ <string name="emulation_input_overlay">화면 오버레이 설정</string>
- <string name="load_settings">설정 불러오기 중...</string>
+ <string name="load_settings">설정 불러오는 중...</string>
<!-- Software keyboard -->
- <string name="software_keyboard">가상 키보드</string>
+ <string name="software_keyboard">소프트웨어 키보드</string>
<!-- Errors and warnings -->
- <string name="abort_button">정보</string>
+ <string name="abort_button">중단</string>
<string name="continue_button">계속</string>
<string name="system_archive_not_found">시스템 아카이브를 찾을 수 없음</string>
<string name="system_archive_not_found_message">%s가 누락되었습니다. 시스템 아카이브를 덤프하세요.\n에뮬레이션을 계속하면 충돌 및 버그가 발생할 수 있습니다.</string>
<string name="system_archive_general">시스템 아카이브</string>
<string name="save_load_error">저장하기/불러오기 오류</string>
- <string name="fatal_error">치명적인 오류</string>
- <string name="fatal_error_message">치명적인 오류가 발생했습니다. 자세한 내용은 로그를 확인하십시오.\n에뮬레이션을 계속하면 충돌 및 버그가 발생할 수 있습니다.</string>
+ <string name="fatal_error">치명적 오류</string>
+ <string name="fatal_error_message">치명적 오류가 발생했습니다. 자세한 내용은 로그를 확인하십시오.\n에뮬레이션을 계속하면 충돌 및 버그가 발생할 수 있습니다.</string>
<string name="performance_warning">이 설정을 끄면 에뮬레이션 성능이 크게 저하됩니다! 최상의 환경을 위해 이 설정을 활성화된 상태로 두는 것이 좋습니다.</string>
-
<!-- Region Names -->
<string name="region_japan">일본</string>
<string name="region_usa">미국</string>
@@ -234,12 +252,11 @@
<string name="region_australia">호주</string>
<string name="region_china">중국</string>
<string name="region_korea">대한민국</string>
- <string name="region_taiwan">타이완</string>
-
- <!-- Language Names -->
+ <string name="region_taiwan">대만</string>
+ <string name="memory_gigabyte">영국 하계 표준시(GB)</string>
<!-- Renderer APIs -->
- <string name="renderer_vulkan">불칸</string>
+ <string name="renderer_vulkan">Vulcan</string>
<string name="renderer_none">없음</string>
<!-- Renderer Accuracy -->
@@ -256,17 +273,17 @@
<string name="resolution_four">4X (2880p/4320p) (느림)</string>
<!-- Renderer VSync -->
- <string name="renderer_vsync_immediate">즉시 (끔)</string>
+ <string name="renderer_vsync_immediate">즉각 표시 (끄기)</string>
<string name="renderer_vsync_mailbox">메일박스</string>
- <string name="renderer_vsync_fifo">FIFO (켬)</string>
- <string name="renderer_vsync_fifo_relaxed">FIFO 릴랙스</string>
+ <string name="renderer_vsync_fifo">FIFO (켜기)</string>
+ <string name="renderer_vsync_fifo_relaxed">FIFO Relaxed</string>
<!-- Scaling Filters -->
- <string name="scaling_filter_nearest_neighbor">가장 가까운 이웃</string>
- <string name="scaling_filter_bilinear">이중선형</string>
- <string name="scaling_filter_bicubic">고등차수보간</string>
+ <string name="scaling_filter_nearest_neighbor">최근접 보간</string>
+ <string name="scaling_filter_bilinear">쌍선형 보간</string>
+ <string name="scaling_filter_bicubic">쌍입방 보간</string>
<string name="scaling_filter_gaussian">가우시안</string>
- <string name="scaling_filter_scale_force">스케일포스</string>
+ <string name="scaling_filter_scale_force">ScaleForce</string>
<string name="scaling_filter_fsr">AMD FidelityFX™ 초고해상도</string>
<!-- Anti-Aliasing -->
@@ -274,27 +291,29 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <string name="screen_layout_auto">자동</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">기본 (16:9)</string>
<string name="ratio_force_four_three">강제 4:3</string>
<string name="ratio_force_twenty_one_nine">강제 21:9</string>
<string name="ratio_force_sixteen_ten">강제 16:10</string>
- <string name="ratio_stretch">창에 맞게 늘림</string>
+ <string name="ratio_stretch">화면에 맞춤</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">정확함</string>
- <string name="cpu_accuracy_unsafe">안전하지 않음</string>
- <string name="cpu_accuracy_paranoid">편집증 (느림)</string>
+ <string name="cpu_accuracy_unsafe">최적화 (안전하지 않음)</string>
+ <string name="cpu_accuracy_paranoid">최적화하지 않음 (느림)</string>
<!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">십자패드</string>
+ <string name="gamepad_d_pad">십자키</string>
<string name="gamepad_left_stick">L 스틱</string>
<string name="gamepad_right_stick">R 스틱</string>
<string name="gamepad_home">홈</string>
<string name="gamepad_screenshot">스크린샷</string>
<!-- Disk shader cache -->
- <string name="preparing_shaders">셰이더 준비하기</string>
+ <string name="preparing_shaders">셰이더 준비하는 중</string>
<string name="building_shaders">셰이더 빌드 중</string>
<!-- Theme options -->
@@ -303,13 +322,19 @@
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
- <string name="change_theme_mode">테마 모드 변경</string>
- <string name="theme_mode_follow_system">팔로우 시스템</string>
- <string name="theme_mode_light">밝음</string>
- <string name="theme_mode_dark">어두움</string>
+ <string name="change_theme_mode">다크 모드 설정</string>
+ <string name="theme_mode_follow_system">시스템 값 사용</string>
+ <string name="theme_mode_light">라이트 모드</string>
+ <string name="theme_mode_dark">다크 모드</string>
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">검은색 배경 사용</string>
- <string name="use_black_backgrounds_description">어두운 테마를 사용할 때는 검은색 배경을 적용합니다.</string>
+ <string name="use_black_backgrounds">검정 배경</string>
+ <string name="use_black_backgrounds_description">어두운 테마를 사용할 때는 검정 배경을 적용합니다.</string>
+
+ <string name="mute">음소거</string>
+ <string name="unmute">음소거 해제</string>
-</resources>
+ <!-- Licenses screen strings -->
+ <string name="licenses">라이센스</string>
+ <string name="license_fidelityfx_fsr_description">AMD의 고품질 업스케일링</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml
index 5443cef42..3162a9d41 100644
--- a/src/android/app/src/main/res/values-nb/strings.xml
+++ b/src/android/app/src/main/res/values-nb/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">Denne programvaren vil kjøre spill for Nintendo Switch-spillkonsollen. Ingen spilltitler eller nøkler er inkludert.&lt;br /&gt;&lt;br /&gt;Før du begynner, må du finne <![CDATA[<b> prod.keys </b>]]> filen din på enhetslagringen.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Lær mer</a>]]></string>
<string name="emulation_notification_channel_name">Emulering er aktiv</string>
@@ -25,7 +25,6 @@
<string name="back">Tilbake</string>
<string name="add_games">Legg til spill</string>
<string name="add_games_description">Velg din spillmappe</string>
-
<!-- Home strings -->
<string name="home_games">Spill</string>
<string name="home_search">Søk</string>
@@ -37,7 +36,7 @@
<string name="add_games_warning">Hoppe over valg av spillmappe?</string>
<string name="add_games_warning_description">Spill vises ikke i Spill-listen hvis en mappe ikke er valgt.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
- <string name="home_search_games">Søk i spill</string>
+ <string name="home_search_games">Søk i spill|</string>
<string name="games_dir_selected">Spillkatalogen er valgt</string>
<string name="install_prod_keys">Installer prod.keys</string>
<string name="install_prod_keys_description">Nødvendig for å dekryptere spill</string>
@@ -61,6 +60,8 @@
<string name="invalid_keys_file">Ugyldig nøkkelfil valgt</string>
<string name="install_keys_success">Nøkler vellykket installert</string>
<string name="reading_keys_failure">Feil ved lesing av krypteringsnøkler</string>
+ <string name="install_prod_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .keys, og prøv igjen.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .bin, og prøv igjen.</string>
<string name="invalid_keys_error">Ugyldige krypteringsnøkler</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">Den valgte filen er feil eller ødelagt. Vennligst dump nøklene på nytt.</string>
@@ -86,7 +87,17 @@
<string name="save_file_invalid_zip_structure_description">Det første undermappenavnet må være spillets tittel-ID.</string>
<string name="import_saves">Importer</string>
<string name="export_saves">Eksporter</string>
-
+ <string name="install_firmware">Installer fastvare</string>
+ <string name="install_firmware_description">Fastvaren må være i et ZIP-arkiv og er nødvendig for å starte noen spill.</string>
+ <string name="firmware_installing">Installering av fastvare</string>
+ <string name="firmware_installed_success">Fastvaren er vellykket installert</string>
+ <string name="firmware_installed_failure">Installasjon av fastvare mislyktes</string>
+ <string name="share_log">Del feilsøkingslogger</string>
+ <string name="share_log_description">Del yuzus loggfil for å feilsøke problemer</string>
+ <string name="share_log_missing">Ingen loggfil funnet</string>
+ <string name="install_game_content">Installer spillinnhold</string>
+ <string name="install_game_content_description">Installer spilloppdateringer eller DLC</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia er ikke ekte</string>
<string name="copied_to_clipboard">Kopiert til utklippstavlen</string>
@@ -94,6 +105,7 @@
<string name="contributors">Bidragsytere</string>
<string name="contributors_description">Laget med \u2764 fra yuzu-teamet</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Prosjekter som gjør yuzu for Android mulig</string>
<string name="build">Bygg</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
@@ -114,41 +126,43 @@
<string name="are_you_interested">Er du interessert?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Aktiver hastighetsbegrensning</string>
- <string name="frame_limit_enable_description">Når aktivert, begrenses emuleringshastigheten til en angitt prosentandel av normal hastighet.</string>
+ <string name="frame_limit_enable">Begrense hastigheten</string>
+ <string name="frame_limit_enable_description">Begrenser emuleringshastigheten til en spesifisert prosentandel av normal hastighet.</string>
<string name="frame_limit_slider">Hastighetsbegrensning i prosent</string>
- <string name="frame_limit_slider_description">Angir prosentandelen som skal begrense emuleringshastigheten. Med standardverdien 100 % vil emuleringen være begrenset til normal hastighet. Høyere eller lavere verdier vil øke eller redusere hastighetsbegrensningen.</string>
+ <string name="frame_limit_slider_description">Angir prosentandelen som skal begrense emuleringshastigheten. 100 % er normal hastighet. Høyere eller lavere verdier vil øke eller redusere hastighetsgrensen.</string>
<string name="cpu_accuracy">CPU-nøyaktighet</string>
-
<!-- System settings strings -->
<string name="use_docked_mode">Dokket modus</string>
- <string name="use_docked_mode_description">Emulerer i dokket modus, noe som øker oppløsningen på bekostning av ytelsen.</string>
+ <string name="use_docked_mode_description">Øker oppløsningen, men reduserer ytelsen. Håndholdt modus brukes når den er deaktivert, noe som reduserer oppløsningen og øker ytelsen.</string>
<string name="emulated_region">Emulert region</string>
<string name="emulated_language">Emulert språk</string>
<string name="select_rtc_date">Velg RTC-dato</string>
<string name="select_rtc_time">Velg RTC-tid</string>
- <string name="use_custom_rtc">Aktiver egendefinert RTC</string>
- <string name="use_custom_rtc_description">Med denne innstillingen kan du stille inn en egendefinert sanntidsklokke som er atskilt fra gjeldende systemtid.</string>
- <string name="set_custom_rtc">Angi egendefinert RTC</string>
+ <string name="use_custom_rtc">Tilpasset Sannhetstidsklokke</string>
+ <string name="use_custom_rtc_description">Gjør det mulig å stille inn en egendefinert sanntidsklokke separat fra den gjeldende systemtiden.</string>
+ <string name="set_custom_rtc">Angi tilpasset RTC</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Nøyaktighetsnivå</string>
- <string name="renderer_resolution">Oppløsning</string>
+ <string name="renderer_resolution">Oppløsning (håndholdt/dokket)</string>
<string name="renderer_vsync">VSync-modus</string>
<string name="renderer_aspect_ratio">Størrelsesforhold</string>
<string name="renderer_scaling_filter">Filter for vindustilpasning</string>
- <string name="renderer_anti_aliasing">Anti-Aliasing-metode</string>
+ <string name="renderer_anti_aliasing">Anti-aliasing-metode</string>
<string name="renderer_force_max_clock">Tving fram maksimal klokkefrekvens (kun Adreno)</string>
<string name="renderer_force_max_clock_description">Tvinger GPU-en til å kjøre med maksimal klokkefrekvens (termiske begrensninger vil fortsatt gjelde).</string>
<string name="renderer_asynchronous_shaders">Bruk asynkrone shaders</string>
- <string name="renderer_asynchronous_shaders_description">Kompilerer shaders asynkront, noe som reduserer hakkingen, men kan føre til feil.</string>
- <string name="renderer_debug">Aktiver feilsøking av grafikk</string>
- <string name="renderer_debug_description">Når dette er merket av, går grafikk-API-et inn i en langsommere feilsøkingsmodus.</string>
- <string name="use_disk_shader_cache">Bruk disk shader-cache</string>
- <string name="use_disk_shader_cache_description">Reduser hakking ved å lagre og laste inn genererte shaders på disken.</string>
-
- <!-- Audio settings strings -->
+ <string name="renderer_asynchronous_shaders_description">Kompilerer shaders asynkront, noe som reduserer hakking, men kan føre til feil.</string>
+ <string name="renderer_reactive_flushing">Bruk reaktiv spyling</string>
+ <string name="renderer_reactive_flushing_description">Forbedrer gjengivelsesnøyaktigheten i enkelte spill på bekostning av ytelsen.</string>
+ <string name="use_disk_shader_cache">Disk shader-hurtigbuffer</string>
+ <string name="use_disk_shader_cache_description">Reduserer hakking ved å lagre og laste inn genererte shaders lokalt.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Feilsøking av grafikk</string>
+ <string name="renderer_debug_description">Setter grafikk-API-et til en langsom feilsøkingsmodus.</string>
<string name="audio_volume">Volum</string>
<string name="audio_volume_description">Angir volumet på lydutgangen.</string>
@@ -164,14 +178,19 @@
<string name="reset_all_settings_description">Alle avanserte innstillinger tilbakestilles til standardkonfigurasjonen. Dette kan ikke angres.</string>
<string name="settings_reset">Tilbakestilling av innstillinger</string>
<string name="close">Lukk</string>
- <string name="learn_more">Lær Mer</string>
-
+ <string name="learn_more">Lær mer</string>
+ <string name="auto">Auto</string>
+ <string name="submit">Send inn</string>
+ <string name="string_null">Null</string>
+ <string name="string_import">Importer</string>
+ <string name="export">Eksporter</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Velg GPU-driver</string>
<string name="select_gpu_driver_title">Ønsker du å bytte ut din nåværende GPU-driver?</string>
<string name="select_gpu_driver_install">Installer</string>
<string name="select_gpu_driver_default">Standard</string>
<string name="select_gpu_driver_use_default">Bruk av standard GPU-driver</string>
+ <string name="select_gpu_driver_error">Ugyldig driver valgt, bruker systemstandard!</string>
<string name="system_gpu_driver">Systemets GPU-driver</string>
<string name="installing_driver">Installerer driver...</string>
@@ -182,10 +201,10 @@
<string name="preferences_graphics">Grafikk</string>
<string name="preferences_audio">Lyd</string>
<string name="preferences_theme">Tema og farge</string>
+ <string name="preferences_debug">Feilsøk</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">ROM-en din er kryptert</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Følg veiledningene for å redumpe dine <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">spillkassetter</a> eller <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">installerte titler</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Vennligst sørg for at <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> filen er installert slik at spillene kan dekrypteres.]]></string>
<string name="loader_error_video_core">Det oppstod en feil ved initialisering av videokjernen</string>
<string name="loader_error_video_core_description">Dette skyldes vanligvis en inkompatibel GPU-driver. Installering av en tilpasset GPU-driver kan løse problemet.</string>
@@ -196,25 +215,25 @@
<string name="emulation_exit">Avslutt emulering</string>
<string name="emulation_done">Ferdig</string>
<string name="emulation_fps_counter">FPS-teller</string>
- <string name="emulation_toggle_controls">Veksle kontroller</string>
- <string name="emulation_rel_stick_center">Relativt senter for stikken</string>
- <string name="emulation_dpad_slide">DPad-skyveplate</string>
- <string name="emulation_haptics">Haptikk</string>
+ <string name="emulation_toggle_controls">Veksle mellom kontrollene</string>
+ <string name="emulation_rel_stick_center">Relativt pinnesenter</string>
+ <string name="emulation_dpad_slide">D-pad-skyving</string>
+ <string name="emulation_haptics">Berøringshaptikk</string>
<string name="emulation_show_overlay">Vis overlegg</string>
- <string name="emulation_toggle_all">Slå av alt</string>
+ <string name="emulation_toggle_all">Veksle mellom alle</string>
<string name="emulation_control_adjust">Juster overlegg</string>
<string name="emulation_control_scale">Skaler</string>
<string name="emulation_control_opacity">Gjennomsiktighet</string>
<string name="emulation_touch_overlay_reset">Tilbakestill overlegg</string>
<string name="emulation_touch_overlay_edit">Rediger overlegg</string>
- <string name="emulation_pause">Pause Emulering</string>
- <string name="emulation_unpause">Opphev pausing av emulering</string>
- <string name="emulation_input_overlay">Alternativer for overlegg</string>
+ <string name="emulation_pause">Pause emulering</string>
+ <string name="emulation_unpause">Ta emuleringen ut av pause</string>
+ <string name="emulation_input_overlay">Overlay-alternativer</string>
<string name="load_settings">Laster inn innstillinger...</string>
<!-- Software keyboard -->
- <string name="software_keyboard">Programvare Tastatur</string>
+ <string name="software_keyboard">Programvaretastatur</string>
<!-- Errors and warnings -->
<string name="abort_button">Avbryt</string>
@@ -226,7 +245,6 @@
<string name="fatal_error">Fatal Feil</string>
<string name="fatal_error_message">Det oppstod en fatal feil. Sjekk loggen for mer informasjon.\nFortsatt emulering kan føre til krasj og feil.</string>
<string name="performance_warning">Hvis du slår av denne innstillingen, reduseres emuleringsytelsen betydelig! Vi anbefaler at du lar denne innstillingen være aktivert for å få den beste opplevelsen.</string>
-
<!-- Region Names -->
<string name="region_japan">Japan</string>
<string name="region_usa">USA</string>
@@ -236,8 +254,7 @@
<string name="region_korea">Korea</string>
<string name="region_taiwan">Taiwan</string>
- <!-- Language Names -->
-
+ <string name="memory_gigabyte">GB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
<string name="renderer_none">Ingen</string>
@@ -274,12 +291,14 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <string name="screen_layout_auto">Auto</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Standard (16:9)</string>
<string name="ratio_force_four_three">Tving 4:3</string>
<string name="ratio_force_twenty_one_nine">Tving 21:9</string>
<string name="ratio_force_sixteen_ten">Tving 16:10</string>
- <string name="ratio_stretch">Strekk til Vindu</string>
+ <string name="ratio_stretch">Strekk til vindu</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">Nøyaktig</string>
@@ -287,9 +306,9 @@
<string name="cpu_accuracy_paranoid">Paranoid (Langsom)</string>
<!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">D-Pad</string>
- <string name="gamepad_left_stick">Venstre Pinne</string>
- <string name="gamepad_right_stick">Høyre Pinne</string>
+ <string name="gamepad_d_pad">D-pad</string>
+ <string name="gamepad_left_stick">Venstre spak</string>
+ <string name="gamepad_right_stick">Høyre spak</string>
<string name="gamepad_home">Hjem</string>
<string name="gamepad_screenshot">Skjermbilde</string>
@@ -298,7 +317,7 @@
<string name="building_shaders">Bygging av shaders</string>
<!-- Theme options -->
- <string name="change_app_theme">Endre appens tema</string>
+ <string name="change_app_theme">Endre app-tema</string>
<string name="theme_default">Standard</string>
<string name="theme_material_you">Material You</string>
@@ -309,7 +328,13 @@
<string name="theme_mode_dark">Mørk</string>
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Bruk svart bakgrunn</string>
+ <string name="use_black_backgrounds">Svart bakgrunn</string>
<string name="use_black_backgrounds_description">Bruk svart bakgrunn når du bruker det mørke temaet.</string>
-</resources>
+ <string name="mute">Lydløs</string>
+ <string name="unmute">Slå på lyden</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Lisenser</string>
+ <string name="license_fidelityfx_fsr_description">Oppskalering av høy kvalitet fra AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml
index 899e233d0..f4d9920c2 100644
--- a/src/android/app/src/main/res/values-pl/strings.xml
+++ b/src/android/app/src/main/res/values-pl/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">To oprogramowanie umożliwia uruchomienie gier z konsoli Nintendo Switch. Nie zawiera gier ani wymaganych kluczy.&lt;br /&gt;&lt;br /&gt;Zanim zaczniesz, wybierz plik kluczy <![CDATA[<b> prod.keys </b>]]> z katalogu w pamięci masowej.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Dowiedz się więcej</a>]]></string>
<string name="emulation_notification_channel_name">Emulacja jest uruchomiona</string>
@@ -25,7 +25,6 @@
<string name="back">Wstecz</string>
<string name="add_games">Dodaj gry</string>
<string name="add_games_description">Wybierz folder zawierający Twoje gry</string>
-
<!-- Home strings -->
<string name="home_games">Gry</string>
<string name="home_search">Szukaj</string>
@@ -61,6 +60,8 @@
<string name="invalid_keys_file">Wybrano niepoprawne klucze</string>
<string name="install_keys_success">Klucze zainstalowane pomyślnie</string>
<string name="reading_keys_failure">Błąd podczas odczytu kluczy</string>
+ <string name="install_prod_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .keys i spróbuj ponownie.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .bin i spróbuj ponownie.</string>
<string name="invalid_keys_error">Niepoprawne klucze</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">Wybrany plik jest niepoprawny lub uszkodzony. Zrzuć ponownie swoje klucze.</string>
@@ -86,7 +87,17 @@
<string name="save_file_invalid_zip_structure_description">Pierwszy podkatalog musi zawierać w nazwie numer ID tytułu gry.</string>
<string name="import_saves">Importuj</string>
<string name="export_saves">Eksportuj</string>
-
+ <string name="install_firmware">Zainstaluj firmware</string>
+ <string name="install_firmware_description">Firmware musi być w postaci archiwum ZIP, niektóre gry wymagają go do uruchomienia/prawidłowego działania</string>
+ <string name="firmware_installing">Instaluję firmware</string>
+ <string name="firmware_installed_success">Zainstalowano pomyślnie</string>
+ <string name="firmware_installed_failure">Błąd podczas instalacji firmware</string>
+ <string name="share_log">Udostępnij logi debugowania</string>
+ <string name="share_log_description">Podziel się logami yuzu, pomoże to twórcom w poprawie działania emulatora</string>
+ <string name="share_log_missing">Nie znaleziono plików logów</string>
+ <string name="install_game_content">Zainstaluj zawartość gry</string>
+ <string name="install_game_content_description">Zainstaluj aktualizację gry lub dodatek DLC</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia isn\'t real</string>
<string name="copied_to_clipboard">Skopiowano do schowka</string>
@@ -94,6 +105,7 @@
<string name="contributors">Współtwórcy</string>
<string name="contributors_description">Stworzone z \u2764 przez zespół yuzu</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Projekty dzięki którym yuzu mógł zostać stworzony</string>
<string name="build">Wersja</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
@@ -114,27 +126,25 @@
<string name="are_you_interested">Jesteś zainteresowany?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Włącz limit szybkości emulacji</string>
+ <string name="frame_limit_enable">Limit szybkość</string>
<string name="frame_limit_enable_description">Włącz, aby ustawić procentowy limit szybkości emulacji</string>
<string name="frame_limit_slider">Procentowy limit szybkości emulacji</string>
<string name="frame_limit_slider_description">Określa limit szybkości emulacji gier. Domyślna wartość 100% oznacza normalną szybkość z jaką działa gra. Wartości niższe lub wyższe zmniejszą lub zwiększą limit szybkości.</string>
<string name="cpu_accuracy">Dokładność procesora CPU</string>
-
<!-- System settings strings -->
<string name="use_docked_mode">Tryb zadokowany</string>
- <string name="use_docked_mode_description">Emulacja w trybie stacji dokującej, zwiększa rozdzielczość kosztem wydajności.</string>
+ <string name="use_docked_mode_description">Zwiększa rozdzielczość kosztem wydajności. Kiedy wyłączone, używany jest tryb Handheld, który obniża rozdzielczość i dzięki temu zwiększa wydajność.</string>
<string name="emulated_region">Region emulacji</string>
<string name="emulated_language">Język emulacji</string>
<string name="select_rtc_date">Ustaw datę RTC</string>
<string name="select_rtc_time">Ustaw czas RTC</string>
- <string name="use_custom_rtc">Włącz niestandardowy zegar RTC</string>
+ <string name="use_custom_rtc">Niestandardowy RTC</string>
<string name="use_custom_rtc_description">Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android.</string>
<string name="set_custom_rtc">Ustaw niestandardowy czas RTC</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">Interfejs graficzny</string>
<string name="renderer_accuracy">Poziom precyzji emulacji</string>
- <string name="renderer_resolution">Rozdzielczość</string>
+ <string name="renderer_resolution">Rozdzielczość (Handheld/Zadokowany)</string>
<string name="renderer_vsync">Synchronizacja pionowa VSync</string>
<string name="renderer_aspect_ratio">Proporcje ekranu</string>
<string name="renderer_scaling_filter">Filtr adaptacji rozdzielczości</string>
@@ -143,12 +153,16 @@
<string name="renderer_force_max_clock_description">Wymusza uruchomienie maksymalnego taktowania układu graficznego (zabezpieczenia termiczne będą dalej aktywne).</string>
<string name="renderer_asynchronous_shaders">Wyłącz synchronizację shaderów</string>
<string name="renderer_asynchronous_shaders_description">Kompiluj oświetlenie bez synchronizacji, poprawi wydajność ale może powodować błędy.</string>
- <string name="renderer_debug">Włącz debugowanie grafiki</string>
- <string name="renderer_debug_description">Kiedy włączone, interfejs graficzny korzysta z wolnego trybu debugowania błędów.</string>
- <string name="use_disk_shader_cache">Użyj pamięci podręcznej shaderów na dysku</string>
+ <string name="renderer_reactive_flushing">Użyj spłukiwania reaktywnego - reactive flushing</string>
+ <string name="renderer_reactive_flushing_description">Poprawia jakość renderowania w kilku grach, kosztem wydajności.</string>
+ <string name="use_disk_shader_cache">Pamięć podręczna shaderów</string>
<string name="use_disk_shader_cache_description">Zmniejsza przycięcia przez przechowywanie gotowych wygenerowanych plików oświetlenia w pamięci urządzenia.</string>
- <!-- Audio settings strings -->
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="renderer_api">Interfejs graficzny</string>
+ <string name="renderer_debug">Debugowanie grafiki</string>
+ <string name="renderer_debug_description">Kiedy włączone, interfejs graficzny korzysta z wolnego trybu debugowania błędów.</string>
<string name="audio_volume">Głośność</string>
<string name="audio_volume_description">Ustala poziom głośności wyjścia dźwięku.</string>
@@ -161,17 +175,21 @@
<string name="reset_setting_confirmation">Przywrócić wartość tego ustawienia do wartości domyślnej?</string>
<string name="reset_to_default">Przywróć ustawienia domyślne</string>
<string name="reset_all_settings">Przywrócić WSZYSTKIE ustawienia?</string>
- <string name="reset_all_settings_description">Wszystkie zaawansowane opcje zostaną przywrócone do wartości domyślnych. Czynności nie będzie można cofnąć.</string>
+ <string name="reset_all_settings_description">Wszystkie zaawansowane opcje zostaną przywrócone do wartości domyślnych. Czynności nie będzie można cofnąć</string>
<string name="settings_reset">Reset ustawień</string>
<string name="close">Zamknij</string>
<string name="learn_more">Dowiedz się więcej</string>
-
+ <string name="auto">Automatyczny</string>
+ <string name="submit">Zatwierdź</string>
+ <string name="string_import">Importuj</string>
+ <string name="export">Eksportuj</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Wybierz sterownik GPU </string>
<string name="select_gpu_driver_title">Chcesz zastąpić obecny sterownik układu graficznego?</string>
<string name="select_gpu_driver_install">Zainstaluj</string>
<string name="select_gpu_driver_default">Domyślne</string>
<string name="select_gpu_driver_use_default">Aktywny domyślny sterownik GPU</string>
+ <string name="select_gpu_driver_error">Wybrano błędny sterownik, powrót do domyślnego. </string>
<string name="system_gpu_driver">Systemowy sterownik GPU</string>
<string name="installing_driver">Instalowanie sterownika...</string>
@@ -182,10 +200,10 @@
<string name="preferences_graphics">Grafika</string>
<string name="preferences_audio">Dźwięk</string>
<string name="preferences_theme">Motyw i kolor</string>
+ <string name="preferences_debug">Debug</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Twój ROM jest zakodowany</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Użyj przewodnika aby wykonać zrzuty <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">kardridży</a> lub <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">zainstalowanych gier</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Upewnij się że plik kluczy <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> jest zainstalowany aby gry mogły zostać odczytane.]]></string>
<string name="loader_error_video_core">Błąd inicjacji podsystemu graficznego</string>
<string name="loader_error_video_core_description">Zazwyczaj spowodowane niekompatybilnym sterownikiem GPU, instalacja niestandardowego sterownika może rozwiązać ten problem.</string>
@@ -198,23 +216,23 @@
<string name="emulation_fps_counter">Licznik FPS</string>
<string name="emulation_toggle_controls">Wybierz przyciski</string>
<string name="emulation_rel_stick_center">Wycentruj gałki</string>
- <string name="emulation_dpad_slide">Ruchomy DPad</string>
+ <string name="emulation_dpad_slide">Ruchomy D-pad</string>
<string name="emulation_haptics">Wibracje haptyczne</string>
<string name="emulation_show_overlay">Pokaż przyciski</string>
- <string name="emulation_toggle_all">Zaznacz wszystkie</string>
+ <string name="emulation_toggle_all">Włącz wszystkie</string>
<string name="emulation_control_adjust">Dostosuj nakładkę</string>
<string name="emulation_control_scale">Skala</string>
<string name="emulation_control_opacity">Przeźroczystość</string>
- <string name="emulation_touch_overlay_reset">Resetuj</string>
+ <string name="emulation_touch_overlay_reset">Resetuj nakładkę</string>
<string name="emulation_touch_overlay_edit">Edytuj nakładkę</string>
<string name="emulation_pause">Wstrzymaj emulację</string>
<string name="emulation_unpause">Wznów emulację</string>
<string name="emulation_input_overlay">Opcje nakładki</string>
- <string name="load_settings">Wczytywanie ustawień...</string>
+ <string name="load_settings">Wczytuję ustawienia...</string>
<!-- Software keyboard -->
- <string name="software_keyboard">Klawiatura systemowa</string>
+ <string name="software_keyboard">Klawiatura programowa</string>
<!-- Errors and warnings -->
<string name="abort_button">Przerwij</string>
@@ -226,7 +244,6 @@
<string name="fatal_error">Błąd krytyczny</string>
<string name="fatal_error_message">Wystąpił błąd krytyczny. Szczegóły znajdziesz w pliku log.\nKontynuowanie może spowodować błędy lub przerwanie emulacji. </string>
<string name="performance_warning">Wyłączenie tej opcji znacząco ograniczy wydajność! Dla najlepszego doświadczenia, zaleca się zostawienie tej opcji włączonej.</string>
-
<!-- Region Names -->
<string name="region_japan">Japonia</string>
<string name="region_usa">USA</string>
@@ -236,8 +253,7 @@
<string name="region_korea">Korea</string>
<string name="region_taiwan">Tajwan</string>
- <!-- Language Names -->
-
+ <string name="memory_gigabyte">GB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
<string name="renderer_none">Żadny</string>
@@ -274,12 +290,14 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <string name="screen_layout_auto">Automatyczny</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Domyślne (16:9)</string>
<string name="ratio_force_four_three">Wymuś 4:3</string>
<string name="ratio_force_twenty_one_nine">Wymuś 21:9</string>
<string name="ratio_force_sixteen_ten">Wymuś 16:10</string>
- <string name="ratio_stretch">Rozciągnij do Okna</string>
+ <string name="ratio_stretch">Rozciągnij do okna</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">Dokładny</string>
@@ -287,7 +305,7 @@
<string name="cpu_accuracy_paranoid">Paranoid (Wolny)</string>
<!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">D-Pad</string>
+ <string name="gamepad_d_pad">D-pad</string>
<string name="gamepad_left_stick">Lewa gałka</string>
<string name="gamepad_right_stick">Prawa gałka</string>
<string name="gamepad_home">Home</string>
@@ -298,18 +316,21 @@
<string name="building_shaders">Budowanie shaderów</string>
<!-- Theme options -->
- <string name="change_app_theme">Zmień motyw aplikacji</string>
+ <string name="change_app_theme">Ustaw motyw aplikacji</string>
<string name="theme_default">Domyślny</string>
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
- <string name="change_theme_mode">Zmiana trybu motywu</string>
+ <string name="change_theme_mode">Zmień tryb motywu</string>
<string name="theme_mode_follow_system">Podążaj za systemowym</string>
<string name="theme_mode_light">Jasny</string>
<string name="theme_mode_dark">Ciemny</string>
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Używaj czarnego tła</string>
+ <string name="use_black_backgrounds">Czarne tła</string>
<string name="use_black_backgrounds_description">Kiedy używany ciemny motyw, tła zostają zastąpione czernią.</string>
-</resources>
+ <!-- Licenses screen strings -->
+ <string name="licenses">Licencje</string>
+ <string name="license_fidelityfx_fsr_description">Rozciąganie wysokiej jakości od AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml
index caa095364..8888fc750 100644
--- a/src/android/app/src/main/res/values-pt-rBR/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml
@@ -1,30 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
- <string name="app_disclaimer">Este software corre jogos para a consola Nintendo Switch. Não estão incluídas nem jogos ou chaves. &lt;br /&gt;&lt;br /&gt;Antes de começares, por favor localiza o ficheiro <![CDATA[1 prod.keys 1]]> no armazenamento do teu dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[2Learn more2]]></string>
+ <string name="app_disclaimer">Este software executa jogos do console Nintendo Switch. Não estão inclusos nem jogos ou chaves. &lt;br /&gt;&lt;br /&gt;Antes de começar, por favor localize o arquivo <![CDATA[1 prod.keys 1]]> no armazenamento de seu dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[2Saiba mais2]]></string>
<string name="emulation_notification_channel_name">Emulação está Ativa</string>
- <string name="emulation_notification_channel_description">Mostra uma notificação permanente enquanto a emulação está a correr.</string>
+ <string name="emulation_notification_channel_description">Mostra uma notificação permanente enquanto a emulação estiver em andamento.</string>
<string name="emulation_notification_running">Yuzu está em execução </string>
<string name="notice_notification_channel_name">Notificações e erros</string>
- <string name="notice_notification_channel_description">Mostra notificações quendo algo corre mal.</string>
- <string name="notification_permission_not_granted">Permissões de notificação não permitidas </string>
+ <string name="notice_notification_channel_description">Mostra notificações quando algo dá errado.</string>
+ <string name="notification_permission_not_granted">Acesso às notificações não concedido!</string>
<!-- Setup strings -->
- <string name="welcome">Bemvindo! </string>
- <string name="welcome_description">Aprende como configurar &lt;b>yuzu&lt;/b> e arranca a emulação.</string>
- <string name="get_started">Começa</string>
- <string name="keys">Chaves</string>
- <string name="keys_description">Seleciona o teu ficheiro &lt;b>prod.keys&lt;/b> com o botão abaixo.</string>
- <string name="select_keys">Seleciona as Chaves</string>
+ <string name="welcome">Bem-vindo! </string>
+ <string name="welcome_description">Aprenda como configurar o &lt;b>yuzu&lt;/b> e mergulhe na emulação.</string>
+ <string name="get_started">Primeiros passos</string>
+ <string name="keys">Keys</string>
+ <string name="keys_description">Selecione seu arquivo &lt;b>prod.keys&lt;/b> com o botão abaixo.</string>
+ <string name="select_keys">Selecione as Keys</string>
<string name="games">Jogos</string>
- <string name="games_description">Seleciona a tua pasta &lt;b>Games&lt;/b> com o botão abaixo.</string>
+ <string name="games_description">Seleciona sua pasta &lt;b>Jogos&lt;/b> com o botão abaixo.</string>
<string name="done">Feito</string>
- <string name="done_description">Tudo pronto.\nDisfruta dos teus jogos!</string>
+ <string name="done_description">Tudo pronto.\nAproveite seus jogos!</string>
<string name="text_continue">Continuar</string>
<string name="next">Próximo</string>
<string name="back">Voltar</string>
- <string name="add_games">Adiciona Jogos</string>
- <string name="add_games_description">Seleciona a tua pasta de Jogos</string>
+ <string name="add_games">Adicionar Jogos</string>
+ <string name="add_games_description">Selecione sua pasta de Jogos</string>
+ <string name="step_complete">Completo!</string>
<!-- Home strings -->
<string name="home_games">Jogos</string>
@@ -37,7 +38,8 @@
<string name="add_games_warning">Ignorar a seleção da pasta de jogos?</string>
<string name="add_games_warning_description">Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
- <string name="home_search_games">Procurar Jogos</string>
+ <string name="home_search_games">Procurar jogos</string>
+ <string name="search_settings">Procurar nas definições</string>
<string name="games_dir_selected">Pasta de Jogos selecionada</string>
<string name="install_prod_keys">Instala prod.keys</string>
<string name="install_prod_keys_description">Necessário para desencriptar jogos comerciais</string>
@@ -61,15 +63,18 @@
<string name="invalid_keys_file">Ficheiro de chaves inválido</string>
<string name="install_keys_success">Chaves instaladas com sucesso</string>
<string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
+ <string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .keys e tente novamente.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .bin e tente novamente.</string>
<string name="invalid_keys_error">Chaves de encriptação inválidas</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string>
<string name="install_gpu_driver">Instala driver para GPU</string>
<string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string>
<string name="advanced_settings">Definições avançadas</string>
+ <string name="advanced_settings_game">Definições avançadas: %1$s</string>
<string name="settings_description">Configura definições do emulador</string>
- <string name="search_recently_played">Jogos recentes</string>
- <string name="search_recently_added">Adicionados recentemente</string>
+ <string name="search_recently_played">Jogado recentemente</string>
+ <string name="search_recently_added">Adicionado recentemente</string>
<string name="search_retail">Jogos comerciais</string>
<string name="search_homebrew">Homebrew</string>
<string name="open_user_folder">Abre a pasta Yuzu</string>
@@ -86,6 +91,33 @@
<string name="save_file_invalid_zip_structure_description">O nome da primeira sub pasta tem de ser a ID do jogo.</string>
<string name="import_saves">Importar</string>
<string name="export_saves">Exportar</string>
+ <string name="install_firmware">Instalar firmware</string>
+ <string name="install_firmware_description">O firmware deve estar em um arquivo ZIP e é necessário para iniciar alguns jogos.</string>
+ <string name="firmware_installing">Instalando firmware</string>
+ <string name="firmware_installed_success">Firmware instalado com sucesso.</string>
+ <string name="firmware_installed_failure">Falha na instalação do firmware</string>
+ <string name="firmware_installed_failure_description">Cofirma que os ficheiros firmware nca estão no root do finheiro zip e tenta de novo.</string>
+ <string name="share_log">Compartilhe registros de debug.</string>
+ <string name="share_log_description">Compartilhe o arquivo de registro do yuzu para obter ajuda com problemas</string>
+ <string name="share_log_missing">Arquivo de registro não encontrado</string>
+ <string name="install_game_content">Instalar conteúdo de jogos</string>
+ <string name="install_game_content_description">Instalar atualizações de jogos ou DLC</string>
+ <string name="installing_game_content">A instalar conteúdo...</string>
+ <string name="install_game_content_failure">Erro ao instalar ficheiro(s) para NAND</string>
+ <string name="install_game_content_failure_description">Por favor confitma que o conteúdo(s) é válido e que as prod.keys estão instaladas.</string>
+ <string name="install_game_content_failure_base">A instalação de jogos base não é permitida para evitar possíveis conflitos.</string>
+ <string name="install_game_content_failure_file_extension">Sò conteúdos NSP e XCI são suportados. Por favor verifica que o conteúdo(s) do jogo são válidos.</string>
+ <string name="install_game_content_failed_count">%1$d erro(s) de instalação</string>
+ <string name="install_game_content_success">Conteúdo(s) de jogo instalados com sucesso</string>
+ <string name="install_game_content_success_install">%1$d instalado com sucesso</string>
+ <string name="install_game_content_success_overwrite">%1$d substituída com êxito</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">Drivers personalizados não suportados</string>
+ <string name="custom_driver_not_supported_description">Carrea«gamento de drivers personalizados não é suportado pr este dispositivo. \nCheck verifica esta opção de futuro para confirmar se o suporte foi adicionado!</string>
+ <string name="manage_yuzu_data">Administrar dados yuzu</string>
+ <string name="manage_yuzu_data_description">Importa/exporta firmware, chaves, dados do usuário e mais!</string>
+ <string name="share_save_file">Partilha ficheiro duardado</string>
+ <string name="export_save_failed">Erro ao exportar dados guardados</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia não é real</string>
@@ -94,7 +126,18 @@
<string name="contributors">Contribuidores</string>
<string name="contributors_description">Feito com \u2764 da equipa do Yuzu</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Projetos que tornam o yuzu para Android possível</string>
<string name="build">Versão</string>
+ <string name="user_data">Dado de utilizados</string>
+ <string name="user_data_description">Importar/exportar todos dados da aplicação data.\n\n Ao importar dados do utilizados, todos os dados existentes do utilizados serão excluídos!</string>
+ <string name="exporting_user_data">A exportar dados de utilizados...</string>
+ <string name="importing_user_data">A importar dados de utilizador...</string>
+ <string name="import_user_data">Importar dados de utilizados...</string>
+ <string name="invalid_yuzu_backup">Backup yuzu inválido</string>
+ <string name="user_data_export_success">Dados de utilizados exportados com sucesso</string>
+ <string name="user_data_import_success">Dados de utilizador importado com sucesso</string>
+ <string name="user_data_export_cancelled">Exportação cancelada</string>
+ <string name="user_data_import_failed_description">Verifiqua se as pastas de dados do utilizados estão na raiz da pasta zip e contêm um arquivo de configuração em config/config.ini e tenta novamente.</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
<string name="are_you_interested">Estás interessado?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Ativar limite de velocidade</string>
- <string name="frame_limit_enable_description">Quando ativada, a velocidade da emulação será limitada à percentagem definida da velocidade normal.</string>
+ <string name="frame_limit_enable">Limite de velocidade</string>
+ <string name="frame_limit_enable_description">Limita a velocidade da emulação a uma porcentagem específica da velocidade normal.</string>
<string name="frame_limit_slider">Percentagem do limite de velocidade</string>
- <string name="frame_limit_slider_description">Especifica o limite da percentagem da velocidade da emulação. Com a velocidade por defeito a 100% a emulação será limitada à velocidade normal. Valores maiores ou menores aumentarão ou diminuirão o limite de velocidade.</string>
+ <string name="frame_limit_slider_description">Especifica a porcentagem para limitar a velocidade de emulação. 100% é o normal. Valores mais altos ou mais baixos irão aumentar ou diminuir o limite de velocidade.</string>
<string name="cpu_accuracy">Precisão do CPU</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
- <string name="use_docked_mode">Modo ancorado</string>
- <string name="use_docked_mode_description">Emula em modo ancorado, que aumenta a resolução ás custas da performance.</string>
+ <string name="use_docked_mode">Modo Ancorado</string>
+ <string name="use_docked_mode_description">Aumenta a resolução, diminuindo o desempenho. O Modo Portátil é utilizado quando estiver desabilitado, diminuindo a resolução e melhorando o desempenho.</string>
<string name="emulated_region">Região da emulação</string>
<string name="emulated_language">Idioma da emulação</string>
- <string name="select_rtc_date">Seleciona a data RTC</string>
- <string name="select_rtc_time">Seleciona a hora RTC</string>
- <string name="use_custom_rtc">Ativa RTC personalizado</string>
- <string name="use_custom_rtc_description">Esta configuração permite definir um RTC personalizado diferente da hora atual do sistema</string>
- <string name="set_custom_rtc">Define RTC personalizado</string>
+ <string name="select_rtc_date">Selecione a data do sistema</string>
+ <string name="select_rtc_time">Selecione a hora do sistema</string>
+ <string name="use_custom_rtc">Data e hora personalizada</string>
+ <string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
+ <string name="set_custom_rtc">Defina um relógio em tempo real personalizado</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Nível de precisão</string>
- <string name="renderer_resolution">Resolução</string>
+ <string name="renderer_resolution">Resolução (Portátil/Ancorado)</string>
<string name="renderer_vsync">Modo VSync</string>
- <string name="renderer_aspect_ratio">Proporção do ecrã</string>
+ <string name="renderer_screen_layout">Oriantação</string>
+ <string name="renderer_aspect_ratio">Proporção da tela</string>
<string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
- <string name="renderer_anti_aliasing">Método de Anti-Aliasing </string>
+ <string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
<string name="renderer_force_max_clock">Força velocidade máxima (Adreno only)</string>
<string name="renderer_force_max_clock_description">Força o GPU a correr à velocidade máxima (restrições térmicas serão aplicadas)</string>
<string name="renderer_asynchronous_shaders">Usa shaders assíncronos </string>
- <string name="renderer_asynchronous_shaders_description">Compila shaders assincronamente, que aumentará a fluidez, mas poderá causar falhas.</string>
+ <string name="renderer_asynchronous_shaders_description">Compila os shaders de forma assíncrona, reduzindo travamentos, mas pode apresentar problemas.</string>
+ <string name="renderer_reactive_flushing">Usar flushing reativo</string>
+ <string name="renderer_reactive_flushing_description">Melhora a precisão da renderização em alguns jogos ao custo de desempenho.</string>
+ <string name="use_disk_shader_cache">Cache de shaders em disco</string>
+ <string name="use_disk_shader_cache_description">Reduz travamentos ao armazenar e carregar localmente os shaders.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">Depuração da CPU</string>
+ <string name="cpu_debug_mode_description">Coloca a CPU em um modo de depuração lento.</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
<string name="renderer_debug">Ativar depuração de gráficos</string>
<string name="renderer_debug_description">Quando selecionado, a API gráfica entra num modo de depuração mais lento.</string>
- <string name="use_disk_shader_cache">Usar cache de shaders em disco</string>
- <string name="use_disk_shader_cache_description">Aumenta a fluidez ao guardar e carregar shaders gerados para o armazenamento.</string>
+ <string name="fastmem">Fastmem</string>
<!-- Audio settings strings -->
+ <string name="audio_output_engine">Motor de saída</string>
<string name="audio_volume">Volume</string>
<string name="audio_volume_description">Especifica o volume de saída.</string>
@@ -157,14 +212,24 @@
<string name="ini_saved">Definições guardadas</string>
<string name="gameid_saved">Definições guardadas para %1$s</string>
<string name="error_saving">Erro ao guardar %1$s.ini: %2$s</string>
+ <string name="unimplemented_menu">Menu não implementado</string>
<string name="loading">A carregar...</string>
+ <string name="shutting_down">A desligar...</string>
<string name="reset_setting_confirmation">Queres reverter esta definição para os valores padrão?</string>
<string name="reset_to_default">Reverter para padrão</string>
<string name="reset_all_settings">Redefinir todas as definições?</string>
- <string name="reset_all_settings_description">Todas as definições avançadas serão redefinidas para as definições padrão. Isto não pode ser revertido.</string>
+ <string name="reset_all_settings_description">Todas as configurações avançadas retornarão ao padrão. Isto não pode ser desfeito.</string>
<string name="settings_reset">Redefinir definições</string>
<string name="close">Fechar</string>
<string name="learn_more">Saiba mais</string>
+ <string name="auto">Automático</string>
+ <string name="submit">Enviar</string>
+ <string name="string_null">Nenhum (desativado)</string>
+ <string name="string_import">Importar</string>
+ <string name="export">Exportar</string>
+ <string name="export_failed">Exportação falhada</string>
+ <string name="import_failed">IMportação falhada</string>
+ <string name="cancelling">A cancelar</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Seleciona a driver para o GPU</string>
@@ -172,6 +237,7 @@
<string name="select_gpu_driver_install">Instalar</string>
<string name="select_gpu_driver_default">Padrão</string>
<string name="select_gpu_driver_use_default">Usar o driver padrão do GPU</string>
+ <string name="select_gpu_driver_error">Driver selecionado inválido, a usar o padrão do sistema!</string>
<string name="system_gpu_driver">Driver do GPU padrão</string>
<string name="installing_driver">A instalar o Driver...</string>
@@ -182,10 +248,11 @@
<string name="preferences_graphics">Gráficos</string>
<string name="preferences_audio">Áudio</string>
<string name="preferences_theme">Cor e tema.</string>
+ <string name="preferences_debug">Depuração</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">A tua ROM está encriptada</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor segue os guias para fazer redump das tuas<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">Cartidges de Jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">Jogos Instalados</a>.]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga os guias para despejar novamente o seu <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartucho de jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">títulos instalados</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Por favor confirma que o teu ficheiro <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado para que os jogos possam ser desencriptados.]]></string>
<string name="loader_error_video_core">Ocorreu um erro ao iniciar o núcleo de vídeo.</string>
<string name="loader_error_video_core_description">Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver GPU pode resolver este problema.</string>
@@ -193,25 +260,25 @@
<string name="loader_error_file_not_found">O ficheiro da ROM não existe</string>
<!-- Emulation Menu -->
- <string name="emulation_exit">Sair da emulação</string>
+ <string name="emulation_exit">Parar emulação</string>
<string name="emulation_done">Feito</string>
<string name="emulation_fps_counter">Contador de FPS</string>
- <string name="emulation_toggle_controls">Alterar Controlos</string>
- <string name="emulation_rel_stick_center">Centro do Analógico Relativo</string>
- <string name="emulation_dpad_slide">Deslizar do DPad</string>
- <string name="emulation_haptics">Hápticos </string>
- <string name="emulation_show_overlay">Mostrar sobreposição </string>
- <string name="emulation_toggle_all">Alterar todos</string>
- <string name="emulation_control_adjust">Ajustar a sobreposição </string>
+ <string name="emulation_toggle_controls">Alterar controles</string>
+ <string name="emulation_rel_stick_center">Centro Relativo de Analógico</string>
+ <string name="emulation_dpad_slide">Deslizamento dos Botões Direcionais</string>
+ <string name="emulation_haptics">Vibração ao tocar</string>
+ <string name="emulation_show_overlay">Mostrar overlay</string>
+ <string name="emulation_toggle_all">Marcar/Desmarcar tudo</string>
+ <string name="emulation_control_adjust">Ajustar overlay</string>
<string name="emulation_control_scale">Escala</string>
<string name="emulation_control_opacity">Opacidade</string>
- <string name="emulation_touch_overlay_reset">Redefinir Sobreposição </string>
- <string name="emulation_touch_overlay_edit">Editar sobreposição </string>
- <string name="emulation_pause">Pausa emulação</string>
+ <string name="emulation_touch_overlay_reset">Restaurar overlay padrão</string>
+ <string name="emulation_touch_overlay_edit">Editar overlay</string>
+ <string name="emulation_pause">Pausar emulação</string>
<string name="emulation_unpause">Retomar emulação</string>
- <string name="emulation_input_overlay">Opções de sobreposição </string>
+ <string name="emulation_input_overlay">Opções de overlay</string>
- <string name="load_settings">Configurações a carregar...</string>
+ <string name="load_settings">Carregando configurações...</string>
<!-- Software keyboard -->
<string name="software_keyboard">Teclado de software</string>
@@ -226,6 +293,9 @@
<string name="fatal_error">Erro fatal</string>
<string name="fatal_error_message">Ocorreu um erro fatal. Verifica o teu registro para detalhes. \nContinuar a emulação pode causar erros.</string>
<string name="performance_warning">Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada.</string>
+ <string name="device_memory_inadequate">RAM do dispositivo: %1$s\nRecommended: %2$s</string>
+ <string name="memory_formatted">%1$s %2$s</string>
+ <string name="no_game_present">Nenhum jogo inicializável presente!</string>
<!-- Region Names -->
<string name="region_japan">Japão</string>
@@ -236,7 +306,14 @@
<string name="region_korea">Coréia</string>
<string name="region_taiwan">Taiwan</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulcano</string>
@@ -274,12 +351,17 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">Landscape</string>
+ <string name="screen_layout_portrait">Portrait</string>
+ <string name="screen_layout_auto">Automático</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Padrão (16:9)</string>
<string name="ratio_force_four_three">Forçar 4:3</string>
<string name="ratio_force_twenty_one_nine">Forçar 21:9</string>
<string name="ratio_force_sixteen_ten">Forçar 16:10</string>
- <string name="ratio_stretch">Esticar para a janela</string>
+ <string name="ratio_stretch">Esticar à janela</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">Preciso</string>
@@ -287,7 +369,7 @@
<string name="cpu_accuracy_paranoid">Paranoid (Lento)</string>
<!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">D-pad</string>
+ <string name="gamepad_d_pad">Botões Direcionais</string>
<string name="gamepad_left_stick">Analógico esquerdo</string>
<string name="gamepad_right_stick">Analógico direito</string>
<string name="gamepad_home">Botão Home</string>
@@ -298,18 +380,32 @@
<string name="building_shaders">A criar shaders</string>
<!-- Theme options -->
- <string name="change_app_theme">Muda o Tema da App</string>
+ <string name="change_app_theme">Mudar o tema do aplicativo</string>
<string name="theme_default">Padrão</string>
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
- <string name="change_theme_mode">Altera o Modo do Tema</string>
+ <string name="change_theme_mode">Alterar o tema</string>
<string name="theme_mode_follow_system">Igual ao Sistema</string>
<string name="theme_mode_light">Claro</string>
<string name="theme_mode_dark">Escuro</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Usa Fundos Negros</string>
+ <string name="use_black_backgrounds">Plano de fundo preto</string>
<string name="use_black_backgrounds_description">Quando usar tema escuro, aplicar fundos escuros</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Picture in Picture</string>
+ <string name="picture_in_picture_description">Minimizar a janela quando colocada em segundo plano</string>
+ <string name="pause">Pausa</string>
+ <string name="play">Correr</string>
+ <string name="mute">Mudo</string>
+ <string name="unmute">Unmute</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Licenças</string>
+ <string name="license_fidelityfx_fsr_description">Upscaling de alta qualidade da AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml
index 0a1a47fbb..6afea9b03 100644
--- a/src/android/app/src/main/res/values-pt-rPT/strings.xml
+++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">Este software corre jogos para a consola Nintendo Switch. Não estão incluídas nem jogos ou chaves. &lt;br /&gt;&lt;br /&gt;Antes de começares, por favor localiza o ficheiro <![CDATA[1 prod.keys 1]]> no armazenamento do teu dispositivo.&lt;br /&gt;&lt;br /&gt;<![CDATA[2Learn more2]]></string>
<string name="emulation_notification_channel_name">Emulação está Ativa</string>
@@ -25,6 +25,7 @@
<string name="back">Voltar</string>
<string name="add_games">Adiciona Jogos</string>
<string name="add_games_description">Seleciona a tua pasta de Jogos</string>
+ <string name="step_complete">Completo!</string>
<!-- Home strings -->
<string name="home_games">Jogos</string>
@@ -37,7 +38,8 @@
<string name="add_games_warning">Ignorar a seleção da pasta de jogos?</string>
<string name="add_games_warning_description">Os jogos não serão exibidos na lista de jogos se uma pasta não estiver selecionada.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
- <string name="home_search_games">Procurar Jogos</string>
+ <string name="home_search_games">Procurar jogos</string>
+ <string name="search_settings">Procurar nas definições</string>
<string name="games_dir_selected">Pasta de Jogos selecionada</string>
<string name="install_prod_keys">Instala prod.keys</string>
<string name="install_prod_keys_description">Necessário para desencriptar jogos comerciais</string>
@@ -61,15 +63,18 @@
<string name="invalid_keys_file">Ficheiro de chaves inválido</string>
<string name="install_keys_success">Chaves instaladas com sucesso</string>
<string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
+ <string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .keys e tente novamente.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .bin e tente novamente.</string>
<string name="invalid_keys_error">Chaves de encriptação inválidas</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string>
<string name="install_gpu_driver">Instala driver para GPU</string>
<string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string>
<string name="advanced_settings">Configurações avançadas</string>
+ <string name="advanced_settings_game">Definições avançadas: %1$s</string>
<string name="settings_description">Configura configurações do emulador</string>
- <string name="search_recently_played">Jogos recentes</string>
- <string name="search_recently_added">Adicionados recentemente</string>
+ <string name="search_recently_played">Jogado recentemente</string>
+ <string name="search_recently_added">Adicionado recentemente</string>
<string name="search_retail">Jogos comerciais</string>
<string name="search_homebrew">Homebrew</string>
<string name="open_user_folder">Abre a pasta Yuzu</string>
@@ -86,6 +91,33 @@
<string name="save_file_invalid_zip_structure_description">O nome da primeira sub pasta tem de ser a ID do jogo.</string>
<string name="import_saves">Importar</string>
<string name="export_saves">Exportar</string>
+ <string name="install_firmware">Instalar firmware</string>
+ <string name="install_firmware_description">O firmware deve estar em um arquivo ZIP e é necessário para iniciar alguns jogos.</string>
+ <string name="firmware_installing">Instalando firmware</string>
+ <string name="firmware_installed_success">Firmware instalado com sucesso.</string>
+ <string name="firmware_installed_failure">Falha na instalação do firmware</string>
+ <string name="firmware_installed_failure_description">Cofirma que os ficheiros firmware nca estão no root do finheiro zip e tenta de novo.</string>
+ <string name="share_log">Compartilhe registros de debug.</string>
+ <string name="share_log_description">Compartilhe o arquivo de registro do yuzu para obter ajuda com problemas</string>
+ <string name="share_log_missing">Arquivo de registro não encontrado</string>
+ <string name="install_game_content">Instalar conteúdo adicional</string>
+ <string name="install_game_content_description">Instale atualizações de jogos ou DLC</string>
+ <string name="installing_game_content">A instalar conteúdo...</string>
+ <string name="install_game_content_failure">Erro ao instalar ficheiro(s) para NAND</string>
+ <string name="install_game_content_failure_description">Por favor confitma que o conteúdo(s) é válido e que as prod.keys estão instaladas.</string>
+ <string name="install_game_content_failure_base">A instalação de jogos base não é permitida para evitar possíveis conflitos.</string>
+ <string name="install_game_content_failure_file_extension">Sò conteúdos NSP e XCI são suportados. Por favor verifica que o conteúdo(s) do jogo são válidos.</string>
+ <string name="install_game_content_failed_count">%1$d erro(s) de instalação</string>
+ <string name="install_game_content_success">Conteúdo(s) de jogo instalados com sucesso</string>
+ <string name="install_game_content_success_install">%1$d instalado com sucesso</string>
+ <string name="install_game_content_success_overwrite">%1$d substituída com êxito</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">Drivers personalizados não suportados</string>
+ <string name="custom_driver_not_supported_description">Carrea«gamento de drivers personalizados não é suportado pr este dispositivo. \nCheck verifica esta opção de futuro para confirmar se o suporte foi adicionado!</string>
+ <string name="manage_yuzu_data">Administrar dados yuzu</string>
+ <string name="manage_yuzu_data_description">Importa/exporta firmware, chaves, dados do usuário e mais!</string>
+ <string name="share_save_file">Partilha ficheiro duardado</string>
+ <string name="export_save_failed">Erro ao exportar dados guardados</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia não é real</string>
@@ -94,7 +126,18 @@
<string name="contributors">Contribuidores</string>
<string name="contributors_description">Feito com \u2764 da equipa do Yuzu</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Projetos que tornam o yuzu para Android possível</string>
<string name="build">Versão</string>
+ <string name="user_data">Dado de utilizados</string>
+ <string name="user_data_description">Importar/exportar todos dados da aplicação data.\n\n Ao importar dados do utilizados, todos os dados existentes do utilizados serão excluídos!</string>
+ <string name="exporting_user_data">A exportar dados de utilizados...</string>
+ <string name="importing_user_data">A importar dados de utilizador...</string>
+ <string name="import_user_data">Importar dados de utilizados...</string>
+ <string name="invalid_yuzu_backup">Backup yuzu inválido</string>
+ <string name="user_data_export_success">Dados de utilizados exportados com sucesso</string>
+ <string name="user_data_import_success">Dados de utilizador importado com sucesso</string>
+ <string name="user_data_export_cancelled">Exportação cancelada</string>
+ <string name="user_data_import_failed_description">Verifiqua se as pastas de dados do utilizados estão na raiz da pasta zip e contêm um arquivo de configuração em config/config.ini e tenta novamente.</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +157,53 @@
<string name="are_you_interested">Estás interessado?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Ativar limite de velocidade</string>
- <string name="frame_limit_enable_description">Quando ativada, a velocidade da emulação será limitada à percentagem definida da velocidade normal.</string>
+ <string name="frame_limit_enable">Limite de velocidade</string>
+ <string name="frame_limit_enable_description">Limita a velocidade da emulação a uma porcentagem específica da velocidade normal.</string>
<string name="frame_limit_slider">Percentagem do limite de velocidade</string>
- <string name="frame_limit_slider_description">Especifica o limite da percentagem da velocidade da emulação. Com a velocidade por defeito a 100% a emulação será limitada à velocidade normal. Valores maiores ou menores aumentarão ou diminuirão o limite de velocidade.</string>
+ <string name="frame_limit_slider_description">Especifica a porcentagem para limitar a velocidade de emulação. 100% é o normal. Valores mais altos ou mais baixos irão aumentar ou diminuir o limite de velocidade.</string>
<string name="cpu_accuracy">Precisão do CPU</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
- <string name="use_docked_mode">Modo ancorado</string>
- <string name="use_docked_mode_description">Emula em modo ancorado, que aumenta a resolução ás custas da performance.</string>
+ <string name="use_docked_mode">Modo Ancorado</string>
+ <string name="use_docked_mode_description">Aumenta a resolução, diminuindo o desempenho. O Modo Portátil é utilizado quando estiver desabilitado, diminuindo a resolução e melhorando o desempenho.</string>
<string name="emulated_region">Região da emulação</string>
<string name="emulated_language">Idioma da emulação</string>
- <string name="select_rtc_date">Seleciona a data RTC</string>
- <string name="select_rtc_time">Seleciona a hora RTC</string>
- <string name="use_custom_rtc">Ativa RTC personalizado</string>
- <string name="use_custom_rtc_description">Esta configuração permite definir um RTC personalizado diferente da hora atual do sistema</string>
- <string name="set_custom_rtc">Define RTC personalizado</string>
+ <string name="select_rtc_date">Selecione a data do sistema</string>
+ <string name="select_rtc_time">Selecione a hora do sistema</string>
+ <string name="use_custom_rtc">RTC personalizado</string>
+ <string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
+ <string name="set_custom_rtc">Defina um relógio em tempo real personalizado</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Nível de precisão</string>
- <string name="renderer_resolution">Resolução</string>
+ <string name="renderer_resolution">Resolução (Portátil/Ancorado)</string>
<string name="renderer_vsync">Modo VSync</string>
- <string name="renderer_aspect_ratio">Proporção do ecrã</string>
+ <string name="renderer_screen_layout">Oriantação</string>
+ <string name="renderer_aspect_ratio">Proporção da tela</string>
<string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
- <string name="renderer_anti_aliasing">Método de Anti-Aliasing </string>
+ <string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
<string name="renderer_force_max_clock">Força velocidade máxima (Adreno only)</string>
<string name="renderer_force_max_clock_description">Força o GPU a correr à velocidade máxima (restrições térmicas serão aplicadas)</string>
<string name="renderer_asynchronous_shaders">Usa shaders assíncronos </string>
- <string name="renderer_asynchronous_shaders_description">Compila shaders assincronamente, que aumentará a fluidez, mas poderá causar falhas.</string>
+ <string name="renderer_asynchronous_shaders_description">Compila os shaders de forma assíncrona, reduzindo travamentos, mas pode apresentar problemas.</string>
+ <string name="renderer_reactive_flushing">Usar flushing reativo</string>
+ <string name="renderer_reactive_flushing_description">Melhora a precisão da renderização em alguns jogos ao custo de desempenho.</string>
+ <string name="use_disk_shader_cache">Cache de shaders em disco</string>
+ <string name="use_disk_shader_cache_description">Reduz travamentos ao armazenar e carregar localmente os shaders.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">Depuração da CPU</string>
+ <string name="cpu_debug_mode_description">Coloca a CPU em um modo de depuração lento.</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
<string name="renderer_debug">Ativar depuração de gráficos</string>
<string name="renderer_debug_description">Quando selecionado, a API gráfica entra num modo de depuração mais lento.</string>
- <string name="use_disk_shader_cache">Usar cache do disk shader</string>
- <string name="use_disk_shader_cache_description">Aumenta a fluidez ao guardar e carregar shaders gerados para o armazenamento.</string>
+ <string name="fastmem">Fastmem</string>
<!-- Audio settings strings -->
+ <string name="audio_output_engine">Motor de saída</string>
<string name="audio_volume">Volume</string>
<string name="audio_volume_description">Especifica o volume de saída.</string>
@@ -157,14 +212,24 @@
<string name="ini_saved">Configurações guardadas</string>
<string name="gameid_saved">Configurações guardadas para %1$s</string>
<string name="error_saving">Erro ao guardar %1$s.ini: %2$s</string>
+ <string name="unimplemented_menu">Menu não implementado</string>
<string name="loading">A carregar...</string>
+ <string name="shutting_down">A desligar...</string>
<string name="reset_setting_confirmation">Queres reverter esta definição para os valores padrão?</string>
<string name="reset_to_default">Reverter para padrão</string>
<string name="reset_all_settings">Redefinir todas as configurações?</string>
- <string name="reset_all_settings_description">Todas as configurações avançadas serão redefinidas para as definições padrão. Isto não pode ser revertido.</string>
+ <string name="reset_all_settings_description">Todas as configurações avançadas retornarão ao padrão. Isto não pode ser desfeito.</string>
<string name="settings_reset">Redefinir configurações </string>
<string name="close">Fechar</string>
- <string name="learn_more">Saber Mais</string>
+ <string name="learn_more">Saber mais</string>
+ <string name="auto">Automático</string>
+ <string name="submit">Enviar</string>
+ <string name="string_null">Nenhum (desativado)</string>
+ <string name="string_import">Importar</string>
+ <string name="export">Exportar</string>
+ <string name="export_failed">Exportação falhada</string>
+ <string name="import_failed">IMportação falhada</string>
+ <string name="cancelling">A cancelar</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Seleciona a driver para o GPU</string>
@@ -172,6 +237,7 @@
<string name="select_gpu_driver_install">Instalar</string>
<string name="select_gpu_driver_default">Padrão</string>
<string name="select_gpu_driver_use_default">Usar o driver padrão do GPU</string>
+ <string name="select_gpu_driver_error">Driver selecionado inválido, a usar o padrão do sistema!</string>
<string name="system_gpu_driver">Driver do GPU padrão</string>
<string name="installing_driver">A instalar o Driver...</string>
@@ -182,10 +248,11 @@
<string name="preferences_graphics">Gráficos</string>
<string name="preferences_audio">Audio</string>
<string name="preferences_theme">Cor e tema.</string>
+ <string name="preferences_debug">Depurar</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">A tua ROM está encriptada</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor segue os guias para fazer redump das tuas<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">Cartidges de Jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">Jogos Instalados</a>.]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga os guias para despejar novamente o seu <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartucho de jogo</a> or <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">títulos instalados</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Por favor confirma que o teu ficheiro <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado para que os jogos possam ser desencriptados.]]></string>
<string name="loader_error_video_core">Ocorreu um erro ao iniciar o núcleo de vídeo.</string>
<string name="loader_error_video_core_description">Isto é normalmente causado por um driver de GPU incompatível. Instalar um driver GPU pode resolver este problema.</string>
@@ -193,28 +260,28 @@
<string name="loader_error_file_not_found">O ficheiro da ROM não existe</string>
<!-- Emulation Menu -->
- <string name="emulation_exit">Sair da emulação</string>
+ <string name="emulation_exit">Parar emulação</string>
<string name="emulation_done">Feito</string>
<string name="emulation_fps_counter">Contador de FPS</string>
- <string name="emulation_toggle_controls">Alterar Controlos</string>
- <string name="emulation_rel_stick_center">Centro do Analógico Relativo</string>
- <string name="emulation_dpad_slide">Deslizar do DPad</string>
- <string name="emulation_haptics">Hápticos </string>
- <string name="emulation_show_overlay">Mostrar sobreposição </string>
- <string name="emulation_toggle_all">Alterar todos</string>
- <string name="emulation_control_adjust">Ajustar a sobreposição </string>
+ <string name="emulation_toggle_controls">Alterar controles</string>
+ <string name="emulation_rel_stick_center">Centro Relativo de Analógico</string>
+ <string name="emulation_dpad_slide">Deslizamento dos Botões Direcionais</string>
+ <string name="emulation_haptics">Vibração ao tocar</string>
+ <string name="emulation_show_overlay">Mostrar overlay</string>
+ <string name="emulation_toggle_all">Marcar/Desmarcar tudo</string>
+ <string name="emulation_control_adjust">Ajustar overlay</string>
<string name="emulation_control_scale">Escala</string>
<string name="emulation_control_opacity">Opacidade</string>
- <string name="emulation_touch_overlay_reset">Redefinir Sobreposição </string>
- <string name="emulation_touch_overlay_edit">Editar sobreposição </string>
- <string name="emulation_pause">Pausa emulação</string>
- <string name="emulation_unpause">Retomar emulação</string>
- <string name="emulation_input_overlay">Opções de sobreposição </string>
+ <string name="emulation_touch_overlay_reset">Restaurar overlay padrão</string>
+ <string name="emulation_touch_overlay_edit">Editar overlay</string>
+ <string name="emulation_pause">Pausar emulação</string>
+ <string name="emulation_unpause">Despausar emulação</string>
+ <string name="emulation_input_overlay">Opções de overlay</string>
- <string name="load_settings">Configurações a carregar...</string>
+ <string name="load_settings">Carregando configurações...</string>
<!-- Software keyboard -->
- <string name="software_keyboard">Teclado de Software</string>
+ <string name="software_keyboard">Teclado de software</string>
<!-- Errors and warnings -->
<string name="abort_button">Abortar</string>
@@ -226,6 +293,9 @@
<string name="fatal_error">Erro fatal</string>
<string name="fatal_error_message">Ocorreu um erro fatal. Verifica o teu registro para detalhes. \nContinuar a emulação pode causar erros.</string>
<string name="performance_warning">Desligar esta configuração irá reduzir a performance da emulação significantemente! Para a melhor experiência é recomendado que deixes esta configuração ativada.</string>
+ <string name="device_memory_inadequate">RAM do dispositivo: %1$s\nRecommended: %2$s</string>
+ <string name="memory_formatted">%1$s %2$s</string>
+ <string name="no_game_present">Nenhum jogo inicializável presente!</string>
<!-- Region Names -->
<string name="region_japan">Japão</string>
@@ -236,7 +306,14 @@
<string name="region_korea">Coreia</string>
<string name="region_taiwan">Taiwan</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulcano</string>
@@ -274,12 +351,17 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">Landscape</string>
+ <string name="screen_layout_portrait">Portrait</string>
+ <string name="screen_layout_auto">Automático</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Padrão (16:9)</string>
<string name="ratio_force_four_three">Forçar 4:3</string>
<string name="ratio_force_twenty_one_nine">Forçar 21:9</string>
<string name="ratio_force_sixteen_ten">Forçar 16:10</string>
- <string name="ratio_stretch">Esticar à Janela</string>
+ <string name="ratio_stretch">Esticar à janela</string>
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">Preciso</string>
@@ -287,9 +369,9 @@
<string name="cpu_accuracy_paranoid">Paranoid (Lento)</string>
<!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">D-Pad</string>
- <string name="gamepad_left_stick">Analógico Esquerdo</string>
- <string name="gamepad_right_stick">Analógico Direito</string>
+ <string name="gamepad_d_pad">Botões Direcionais</string>
+ <string name="gamepad_left_stick">Analógico esquerdo</string>
+ <string name="gamepad_right_stick">Analógico direito</string>
<string name="gamepad_home">Home</string>
<string name="gamepad_screenshot">Captura de ecrã</string>
@@ -298,18 +380,32 @@
<string name="building_shaders">A criar shaders</string>
<!-- Theme options -->
- <string name="change_app_theme">Muda o Tema da App</string>
+ <string name="change_app_theme">Mudar o tema do aplicativo</string>
<string name="theme_default">Padrão</string>
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
- <string name="change_theme_mode">Altera o Modo do Tema</string>
+ <string name="change_theme_mode">Alterar o tema</string>
<string name="theme_mode_follow_system">Igual ao Sistema</string>
<string name="theme_mode_light">Claro</string>
<string name="theme_mode_dark">Escuro</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Usa Fundos Escuros</string>
+ <string name="use_black_backgrounds">Plano de fundo preto</string>
<string name="use_black_backgrounds_description">Quando usar tema escuro, aplicar fundos escuros</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Picture in Picture</string>
+ <string name="picture_in_picture_description">Minimizar a janela quando colocada em segundo plano</string>
+ <string name="pause">Pausa</string>
+ <string name="play">Correr</string>
+ <string name="mute">Mute</string>
+ <string name="unmute">Unmute</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Licenças</string>
+ <string name="license_fidelityfx_fsr_description">Upscaling de alta qualidade da AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml
index 0bef035d6..c614257a8 100644
--- a/src/android/app/src/main/res/values-ru/strings.xml
+++ b/src/android/app/src/main/res/values-ru/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">Это программное обеспечение позволяет запускать игры для игровой консоли Nintendo Switch. Мы не предоставляем сами игры или ключи.&lt;br /&gt;&lt;br /&gt;Перед началом работы найдите файл <![CDATA[<b> prod.keys </b>]]> в хранилище устройства..&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Узнать больше</a>]]></string>
<string name="emulation_notification_channel_name">Эмуляция активна</string>
@@ -7,7 +7,7 @@
<string name="emulation_notification_running">yuzu запущен</string>
<string name="notice_notification_channel_name">Уведомления и ошибки</string>
<string name="notice_notification_channel_description">Показывать уведомления, когда что-то пошло не так</string>
- <string name="notification_permission_not_granted">Вы не предоставили разрешение уведомлений!</string>
+ <string name="notification_permission_not_granted">Вы не предоставили разрешение на уведомления!</string>
<!-- Setup strings -->
<string name="welcome">Добро пожаловать!</string>
@@ -25,6 +25,7 @@
<string name="back">Назад</string>
<string name="add_games">Добавить игры</string>
<string name="add_games_description">Выберите папку с играми</string>
+ <string name="step_complete">Выполнено!</string>
<!-- Home strings -->
<string name="home_games">Игры</string>
@@ -38,6 +39,7 @@
<string name="add_games_warning_description">Игры не будут отображаться в списке Игры, если папка не выбрана.</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">Найти игры</string>
+ <string name="search_settings">Настройки поиска</string>
<string name="games_dir_selected">Выбрана папка с играми</string>
<string name="install_prod_keys">Установить prod.keys</string>
<string name="install_prod_keys_description">Требуется для расшифровки розничных игр</string>
@@ -61,14 +63,17 @@
<string name="invalid_keys_file">Выбран неверный файл ключей</string>
<string name="install_keys_success">Ключи успешно установлены</string>
<string name="reading_keys_failure">Ошибка при чтении ключей шифрования</string>
+ <string name="install_prod_keys_failure_extension_description">Убедитесь, что файл ключей имеет расширение .keys, и повторите попытку.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Убедитесь, что файл ключей имеет расширение .bin, и повторите попытку.</string>
<string name="invalid_keys_error">Неверные ключи шифрования</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">Выбранный файл неверен или поврежден. Пожалуйста, пере-дампите ваши ключи.</string>
<string name="install_gpu_driver">Установить драйвер ГП</string>
<string name="install_gpu_driver_description">Установите альтернативные драйверы для потенциально лучшей производительности и/или точности</string>
<string name="advanced_settings">Расширенные настройки</string>
+ <string name="advanced_settings_game">Расширенные настройки: %1$s</string>
<string name="settings_description">Настройка параметров эмулятора</string>
- <string name="search_recently_played">Недавно сыграно</string>
+ <string name="search_recently_played">Недавно сыгранные</string>
<string name="search_recently_added">Недавно добавлено</string>
<string name="search_retail">Розничные</string>
<string name="search_homebrew">Homebrew</string>
@@ -86,6 +91,34 @@
<string name="save_file_invalid_zip_structure_description">Название первой вложенной папки должно быть идентификатором игры.</string>
<string name="import_saves">Импорт</string>
<string name="export_saves">Экспорт</string>
+ <string name="install_firmware">Установить прошивку</string>
+ <string name="install_firmware_description">Прошивка должна находиться в ZIP-архиве и необходима для загрузки некоторых игр</string>
+ <string name="firmware_installing">Установка прошивки</string>
+ <string name="firmware_installed_success">Прошивка успешно установлена</string>
+ <string name="firmware_installed_failure">Не удалось установить прошивку</string>
+ <string name="firmware_installed_failure_description">Убедитесь что файлы прошивки nca находятся в корне zip-архива и повторите попытку.</string>
+ <string name="share_log">Поделиться журналом отладки</string>
+ <string name="share_log_description">Поделиться журналом отладки yuzu для устранения проблем</string>
+ <string name="share_log_missing">Файл журнала не найден</string>
+ <string name="install_game_content">Установить игровой контент</string>
+ <string name="install_game_content_description">Установить обновления игры или дополнений</string>
+ <string name="installing_game_content">Установка контента...</string>
+ <string name="install_game_content_failure">Ошибка установки файл(ов) в NAND.</string>
+ <string name="install_game_content_failure_description">Убедитесь что содержимое допустимо и что файл prod.keys установлен.</string>
+ <string name="install_game_content_failure_base">Установка базовых игр запрещена во избежание возможных конфликтов.</string>
+ <string name="install_game_content_failure_file_extension">Поддерживается только контент NSP и XCI. Пожалуйста убедитесь что игровой контент действителен.</string>
+ <string name="install_game_content_failed_count">%1$d ошибка установки</string>
+ <string name="install_game_content_success">Игровой контент успешно установлен</string>
+ <string name="install_game_content_success_install">%1$d Успешно установлено</string>
+ <string name="install_game_content_success_overwrite">%1$d Успешно перезаписано</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">Пользовательские драйверы не поддерживаются</string>
+ <string name="custom_driver_not_supported_description">Загрузка пользовательского драйвера в настоящее время не поддерживается для этого устройства.\nПроверьте этот параметр еще раз в будущем чтобы узнать была ли добавлена ​​поддержка!
+ </string>
+ <string name="manage_yuzu_data">Управление данными yuzu</string>
+ <string name="manage_yuzu_data_description">Импортируйте/экспортируйте прошивку, ключи, пользовательские данные и многое другое!</string>
+ <string name="share_save_file">Поделиться файлом сохранения</string>
+ <string name="export_save_failed">Не удалось экспортировать сохранение</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia не существует</string>
@@ -94,7 +127,18 @@
<string name="contributors">Контрибьюторы</string>
<string name="contributors_description">Сделано с \u2764 от команды yuzu</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Проекты, которые сделали yuzu для Android возможным</string>
<string name="build">Сборка</string>
+ <string name="user_data">Данные пользователя</string>
+ <string name="user_data_description">Импортируйте/экспортируйте все данные приложения.\n\nПри импорте пользовательских данных все существующие пользовательские данные будут удалены!</string>
+ <string name="exporting_user_data">Экспорт пользовательских данных…</string>
+ <string name="importing_user_data">Импорт пользовательских данных…</string>
+ <string name="import_user_data">Импортировать пользовательские данные</string>
+ <string name="invalid_yuzu_backup">Неверная резервная копия yuzu</string>
+ <string name="user_data_export_success">Пользовательские данные успешно экспортированы</string>
+ <string name="user_data_import_success">Пользовательские данные успешно импортированы</string>
+ <string name="user_data_export_cancelled">Экспорт отменен</string>
+ <string name="user_data_import_failed_description">Убедитесь что папки пользовательских данных находятся в корне zip-папки и содержат файл конфигурации config/config.ini и повторите попытку.</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,41 +158,51 @@
<string name="are_you_interested">Вы заинтересованы?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">Включить ограничение скорости</string>
- <string name="frame_limit_enable_description">Если эта функция включена, скорость эмуляции будет ограничена указанным процентом от нормальной скорости.</string>
+ <string name="frame_limit_enable">Ограничить скорость</string>
+ <string name="frame_limit_enable_description">Ограничивает скорость эмуляции указанным процентом от нормальной скорости.</string>
<string name="frame_limit_slider">Ограничение процента cкорости</string>
- <string name="frame_limit_slider_description">Указывает процент для ограничения скорости эмуляции. При значении по умолчанию 100% эмуляция будет ограничена нормальной скоростью. Значения выше или ниже будут увеличивать или уменьшать ограничение скорости.</string>
+ <string name="frame_limit_slider_description">Указывает процент ограничения скорости эмуляции. 100% - это нормальная скорость. Значения больше или меньше увеличивают или уменьшают ограничение скорости.</string>
<string name="cpu_accuracy">Точность ЦП</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
<string name="use_docked_mode">Режим док-станции</string>
- <string name="use_docked_mode_description">Эмуляция режима док-станции, что увеличивает разрешение за счет снижения производительности.</string>
- <string name="emulated_region">Эмулируемый регион</string>
- <string name="emulated_language">Эмулируемый язык</string>
+ <string name="use_docked_mode_description">Увеличивает разрешение, снижая производительность. Портативный режим используется при отключении, снижая разрешение и повышая производительность.</string>
+ <string name="emulated_region">Регион консоли</string>
+ <string name="emulated_language">Язык консоли</string>
<string name="select_rtc_date">Выберите дату RTC</string>
<string name="select_rtc_time">Выберите время RTC</string>
- <string name="use_custom_rtc">Включить пользовательский RTC</string>
- <string name="use_custom_rtc_description">Этот параметр позволяет установить пользовательские часы реального времени отдельно от текущего системного времени</string>
+ <string name="use_custom_rtc">Пользовательский RTC</string>
+ <string name="use_custom_rtc_description">Позволяет установить пользовательские часы реального времени отдельно от текущего системного времени.</string>
<string name="set_custom_rtc">Установить пользовательский RTC</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Уровень точности</string>
- <string name="renderer_resolution">Разрешение</string>
+ <string name="renderer_resolution">Разрешение (портативное/в док-станции)</string>
<string name="renderer_vsync">Режим верт. синхронизации</string>
+ <string name="renderer_screen_layout">Ориентация</string>
<string name="renderer_aspect_ratio">Соотношение сторон</string>
<string name="renderer_scaling_filter">Фильтр адаптации окна</string>
<string name="renderer_anti_aliasing">Метод сглаживания</string>
<string name="renderer_force_max_clock">Принудительно заставить максимальную тактовую частоту (только для Adreno)</string>
<string name="renderer_force_max_clock_description">Заставляет ГП работать на максимально возможных тактовых частотах (тепловые ограничения все равно будут применяться).</string>
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
- <string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно, что уменьшает зависания, но может взамен предоставить визуальные баги.</string>
- <string name="renderer_debug">Включить отладку графики</string>
- <string name="renderer_debug_description">Если включено, графический API переходит в более медленный режим отладки</string>
- <string name="use_disk_shader_cache">Использовать кэш шейдеров на диске</string>
- <string name="use_disk_shader_cache_description">Уменьшение зависаний за счет хранения и загрузки сгенерированных шейдеров на хранилище.</string>
+ <string name="renderer_asynchronous_shaders_description">Компиляция шейдеров происходит асинхронно, что уменьшает зависания, но может привести к появлению багов.</string>
+ <string name="renderer_reactive_flushing">Реактивная очистка</string>
+ <string name="renderer_reactive_flushing_description">Повышение точности рендеринга в некоторых играх за счет снижения производительности.</string>
+ <string name="use_disk_shader_cache">Кэш шейдеров на диске</string>
+ <string name="use_disk_shader_cache_description">Уменьшение зависаний за счет хранения и загрузки сгенерированных шейдеров.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">ЦП</string>
+ <string name="cpu_debug_mode">Отладка ЦП</string>
+ <string name="cpu_debug_mode_description">Переводит ЦП в режим медленной отладки.</string>
+ <string name="gpu">графический процессор</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Отладка графики</string>
+ <string name="renderer_debug_description">Переводит графический API в режим медленной отладки.</string>
+ <string name="fastmem">Fastmem</string>
- <!-- Audio settings strings -->
<string name="audio_volume">Громкость</string>
<string name="audio_volume_description">Задает громкость аудиовыхода.</string>
@@ -157,7 +211,9 @@
<string name="ini_saved">Сохраненные настройки</string>
<string name="gameid_saved">Настройки сохранены для %1$s</string>
<string name="error_saving">Ошибка сохранения %1$s.ini: %2$s</string>
+ <string name="unimplemented_menu">Нереализованное меню</string>
<string name="loading">Загрузка...</string>
+ <string name="shutting_down">Выключение…</string>
<string name="reset_setting_confirmation">Хотите ли вы вернуть этот параметр к значению по умолчанию?</string>
<string name="reset_to_default">Сброс к настройкам по умолчанию</string>
<string name="reset_all_settings">Сбросить все настройки?</string>
@@ -165,6 +221,14 @@
<string name="settings_reset">Настройки сброшены</string>
<string name="close">Закрыть</string>
<string name="learn_more">Узнать больше</string>
+ <string name="auto">Авто</string>
+ <string name="submit">Отправить</string>
+ <string name="string_null">Null</string>
+ <string name="string_import">Импорт</string>
+ <string name="export">Экспорт</string>
+ <string name="export_failed">Ошибка экспорта</string>
+ <string name="import_failed">Ошибка импортирования</string>
+ <string name="cancelling">Отменяю</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Выбрать драйвер ГП</string>
@@ -172,6 +236,7 @@
<string name="select_gpu_driver_install">Установить</string>
<string name="select_gpu_driver_default">По умолчанию</string>
<string name="select_gpu_driver_use_default">Используется стандартный драйвер ГП </string>
+ <string name="select_gpu_driver_error">Выбран неверный драйвер, используется стандартный системный!</string>
<string name="system_gpu_driver">Системный драйвер ГП</string>
<string name="installing_driver">Установка драйвера...</string>
@@ -182,10 +247,11 @@
<string name="preferences_graphics">Графика</string>
<string name="preferences_audio">Аудио</string>
<string name="preferences_theme">Тема и цвет</string>
+ <string name="preferences_debug">Отладка</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Ваш ROM зашифрованный</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Пожалуйста, следуйте инструкциям, чтобы пере-дампить ваши <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">игровые картриджи</a> или <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">установленные игры</a>.]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[Следуйте инструкциям, чтобы пере-дампить игровые картриджи <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\"> или <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\"> установленные игры</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Пожалуйста, убедитесь, что ваш файл <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> установлен, чтобы игры можно было расшифровать.]]></string>
<string name="loader_error_video_core">Произошла ошибка при инициализации видеоядра.</string>
<string name="loader_error_video_core_description">Обычно это вызвано несовместимым драйвером ГП. Установка пользовательского драйвера ГП может решить эту проблему.</string>
@@ -199,17 +265,17 @@
<string name="emulation_toggle_controls">Переключение управления</string>
<string name="emulation_rel_stick_center">Относительный центр стика</string>
<string name="emulation_dpad_slide">Слайд крестовиной</string>
- <string name="emulation_haptics">Тактильная обратная связь</string>
+ <string name="emulation_haptics">Обратная связь от нажатий</string>
<string name="emulation_show_overlay">Показать оверлей</string>
<string name="emulation_toggle_all">Переключить всё</string>
- <string name="emulation_control_adjust">Настроить оверлей</string>
+ <string name="emulation_control_adjust">Регулировка оверлея</string>
<string name="emulation_control_scale">Масштаб</string>
<string name="emulation_control_opacity">Непрозрачность</string>
<string name="emulation_touch_overlay_reset">Сбросить оверлей</string>
- <string name="emulation_touch_overlay_edit">Изменить оверлей</string>
+ <string name="emulation_touch_overlay_edit">Редактировать оверлей</string>
<string name="emulation_pause">Пауза эмуляции</string>
- <string name="emulation_unpause">Возобновление эмуляции</string>
- <string name="emulation_input_overlay">Настройки оверлея</string>
+ <string name="emulation_unpause">Возобновить эмуляцию</string>
+ <string name="emulation_input_overlay">Настройка оверлея</string>
<string name="load_settings">Загрузка настроек...</string>
@@ -226,6 +292,9 @@
<string name="fatal_error">Фатальная ошибка</string>
<string name="fatal_error_message">Произошла фатальная ошибка. Проверьте журнал для получения подробной информации.\nПродолжение эмуляции может привести к сбоям и ошибкам.</string>
<string name="performance_warning">Отключение этой настройки значительно снизит производительность эмуляции! Для достижения наилучших результатов рекомендуется оставить эту настройку включенной.</string>
+ <string name="device_memory_inadequate">Оперативная память устройства: %1$s\nРекомендовано: %2$s</string>
+ <string name="memory_formatted">%1$s%2$s</string>
+ <string name="no_game_present">Загрузочной игры нету!</string>
<!-- Region Names -->
<string name="region_japan">Япония</string>
@@ -236,7 +305,14 @@
<string name="region_korea">Корея</string>
<string name="region_taiwan">Тайвань</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Байт</string>
+ <string name="memory_kilobyte">КБ</string>
+ <string name="memory_megabyte">МБ</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">ТБ</string>
+ <string name="memory_petabyte">ПБ</string>
+ <string name="memory_exabyte">ЕВ</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +350,11 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">Пейзаж</string>
+ <string name="screen_layout_portrait">Портрет</string>
+ <string name="screen_layout_auto">Авто</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">Стандартное (16:9)</string>
<string name="ratio_force_four_three">Заставить 4:3</string>
@@ -288,8 +369,8 @@
<!-- Gamepad Buttons -->
<string name="gamepad_d_pad">Крестовина</string>
- <string name="gamepad_left_stick">Левый мини-джойстик</string>
- <string name="gamepad_right_stick">Правый мини-джойстик</string>
+ <string name="gamepad_left_stick">Левый стик</string>
+ <string name="gamepad_right_stick">Правый стик</string>
<string name="gamepad_home">Home</string>
<string name="gamepad_screenshot">Скриншот</string>
@@ -298,18 +379,32 @@
<string name="building_shaders">Постройка шейдеров</string>
<!-- Theme options -->
- <string name="change_app_theme">Изменить тему приложения</string>
+ <string name="change_app_theme">Сменить тему</string>
<string name="theme_default">По умолчанию</string>
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
- <string name="change_theme_mode">Изменить режим темы</string>
+ <string name="change_theme_mode">Сменить режим темы</string>
<string name="theme_mode_follow_system">Системная</string>
<string name="theme_mode_light">Светлая</string>
<string name="theme_mode_dark">Темная</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Использовать черный фон</string>
+ <string name="use_black_backgrounds">Чёрный фон</string>
<string name="use_black_backgrounds_description">При использовании темной темы применяйте черный фон.</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">Картинка в картинке</string>
+ <string name="picture_in_picture_description">Свернуть окно при размещении в фоновом режиме</string>
+ <string name="pause">Пауза</string>
+ <string name="play">Играть</string>
+ <string name="mute">Выключить звук</string>
+ <string name="unmute">Включить звук</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Лицензии</string>
+ <string name="license_fidelityfx_fsr_description">Высококачественное масштабирование от AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml
index 5b789ee98..34809dbb8 100644
--- a/src/android/app/src/main/res/values-uk/strings.xml
+++ b/src/android/app/src/main/res/values-uk/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">Це програмне забезпечення дозволяє запускати ігри для ігрової консолі Nintendo Switch. Ми не надаємо самі ігри або ключі.&lt;br /&gt;&lt;br /&gt;Перед початком роботи знайдіть ваш файл <![CDATA[<b> prod.keys </b>]]> у сховищі пристрою.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Дізнатися більше</a>]]></string>
<string name="emulation_notification_channel_name">Емуляція активна</string>
@@ -25,7 +25,6 @@
<string name="back">Назад</string>
<string name="add_games">Додати ігри</string>
<string name="add_games_description">Виберіть папку з іграми</string>
-
<!-- Home strings -->
<string name="home_games">Ігри</string>
<string name="home_search">Пошук</string>
@@ -61,6 +60,7 @@
<string name="invalid_keys_file">Вибрано неправильний файл ключів</string>
<string name="install_keys_success">Ключі успішно встановлено</string>
<string name="reading_keys_failure">Помилка під час зчитування ключів шифрування</string>
+ <string name="install_prod_keys_failure_extension_description">Переконайтеся, що файл ключів має розширення .keys, і повторіть спробу.</string>
<string name="invalid_keys_error">Невірні ключі шифрування</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">Обраний файл невірний або пошкоджений. Будь ласка, пере-дампіть ваші ключі.</string>
@@ -68,8 +68,6 @@
<string name="install_gpu_driver_description">Встановіть альтернативні драйвери для потенційно кращої продуктивності та/або точності</string>
<string name="advanced_settings">Розширені налаштування</string>
<string name="settings_description">Налаштування параметрів емулятора</string>
- <string name="search_recently_played">Нещодавно зіграно</string>
- <string name="search_recently_added">Нещодавно додано</string>
<string name="search_retail">Роздрібні</string>
<string name="search_homebrew">Homebrew</string>
<string name="open_user_folder">Відкрити папку yuzu</string>
@@ -86,7 +84,6 @@
<string name="save_file_invalid_zip_structure_description">Назва першої вкладеної папки має бути ідентифікатором гри.</string>
<string name="import_saves">Імпорт</string>
<string name="export_saves">Експорт</string>
-
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia не існує</string>
<string name="copied_to_clipboard">Скопійовано в буфер обміну</string>
@@ -113,42 +110,20 @@
<string name="our_eternal_gratitude">Наша нескінченна вдячність</string>
<string name="are_you_interested">Ви зацікавлені?</string>
- <!-- General settings strings -->
- <string name="frame_limit_enable">Увімкнути обмеження швидкості</string>
- <string name="frame_limit_enable_description">Якщо цю функцію ввімкнено, швидкість емуляції буде обмежена зазначеним відсотком від нормальної швидкості.</string>
<string name="frame_limit_slider">Обмеження відсотка швидкості</string>
- <string name="frame_limit_slider_description">Вказує відсоток для обмеження швидкості емуляції. При значенні за замовчуванням 100% емуляція буде обмежена нормальною швидкістю. Значення вище або нижче збільшуватимуть або зменшуватимуть обмеження швидкості.</string>
<string name="cpu_accuracy">Точність ЦП</string>
-
- <!-- System settings strings -->
- <string name="use_docked_mode">Режим док-станції</string>
- <string name="use_docked_mode_description">Емуляція режиму док-станції, що збільшує роздільну здатність за рахунок зниження продуктивності.</string>
<string name="emulated_region">Емульований регіон</string>
<string name="emulated_language">Емульована мова</string>
- <string name="select_rtc_date">Оберіть дату RTC</string>
- <string name="select_rtc_time">Оберіть час RTC</string>
- <string name="use_custom_rtc">Увімкнути користувацький RTC</string>
- <string name="use_custom_rtc_description">Цей параметр дає змогу встановити користувацький годинник реального часу окремо від поточного системного часу</string>
- <string name="set_custom_rtc">Встановити користувацький RTC</string>
-
+ <string name="use_custom_rtc">Користувацький RTC</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">Рівень точності</string>
- <string name="renderer_resolution">Роздільна здатність</string>
<string name="renderer_vsync">Режим верт. синхронізації</string>
- <string name="renderer_aspect_ratio">Співвідношення сторін</string>
- <string name="renderer_scaling_filter">Фільтр адаптації вікна</string>
- <string name="renderer_anti_aliasing">Метод згладжування</string>
<string name="renderer_force_max_clock">Примусово змусити максимальну тактову частоту (тільки для Adreno)</string>
<string name="renderer_force_max_clock_description">Змушує ГП працювати на максимально можливих тактових частотах (теплові обмеження все одно будуть застосовуватися).</string>
<string name="renderer_asynchronous_shaders">Використовувати асинхронні шейдери</string>
- <string name="renderer_asynchronous_shaders_description">Компілює шейдери асинхронно, що зменшує зависання, але може натомість надати візуальні баги.</string>
- <string name="renderer_debug">Увімкнути налагодження графіки</string>
- <string name="renderer_debug_description">Якщо увімкнено, графічний API переходить у повільніший режим налагодження</string>
- <string name="use_disk_shader_cache">Використовувати кеш шейдерів на диску</string>
- <string name="use_disk_shader_cache_description">Зменшення зависань завдяки зберіганню та завантаженню згенерованих шейдерів на сховище.</string>
-
- <!-- Audio settings strings -->
+ <!-- Debug settings strings -->
+ <string name="cpu">ЦП</string>
+ <string name="renderer_api">API</string>
<string name="audio_volume">Гучність</string>
<string name="audio_volume_description">Вказує гучність аудіовиходу.</string>
@@ -161,17 +136,20 @@
<string name="reset_setting_confirmation">Чи хочете ви повернути цей параметр до значення за замовчуванням?</string>
<string name="reset_to_default">Скидання до налаштувань за замовчуванням</string>
<string name="reset_all_settings">Скинути всі налаштування</string>
- <string name="reset_all_settings_description">Усі додаткові налаштування буде скинуто до налаштування за замовчуванням. Це неможливо скасувати.</string>
<string name="settings_reset">Налаштування скинуто</string>
<string name="close">Закрити</string>
<string name="learn_more">Дізнатися більше</string>
-
+ <string name="auto">Авто</string>
+ <string name="string_null">Null</string>
+ <string name="string_import">Імпорт</string>
+ <string name="export">Експорт</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Вибрати драйвер ГП</string>
<string name="select_gpu_driver_title">Хочете замінити поточний драйвер ГП?</string>
<string name="select_gpu_driver_install">Встановити</string>
<string name="select_gpu_driver_default">За замовчуванням</string>
<string name="select_gpu_driver_use_default">Використовується стандартний драйвер ГП</string>
+ <string name="select_gpu_driver_error">Обрано неправильний драйвер, використовується стандартний системний!</string>
<string name="system_gpu_driver">Системний драйвер ГП</string>
<string name="installing_driver">Встановлення драйвера...</string>
@@ -182,40 +160,19 @@
<string name="preferences_graphics">Графіка</string>
<string name="preferences_audio">Аудіо</string>
<string name="preferences_theme">Тема і колір</string>
+ <string name="preferences_debug">Налагодження</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Ваш ROM зашифрований</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[Будь ласка, дотримуйтесь інструкцій, щоб пере-дампити ваші <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">ігрові картриджі</a> або <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">встановлені ігри</a>.]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[Будь ласка, переконайтеся, що ваш файл <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> встановлено, щоб ігри можна було розшифрувати.]]></string>
<string name="loader_error_video_core">Сталася помилка під час ініціалізації відеоядра.</string>
<string name="loader_error_video_core_description">Зазвичай це спричинено несумісним драйвером ГП. Встановлення користувацького драйвера ГП може вирішити цю проблему.</string>
<string name="loader_error_invalid_format">Не вдалося запустити ROM</string>
<string name="loader_error_file_not_found">Файл ROM не існує</string>
- <!-- Emulation Menu -->
- <string name="emulation_exit">Вихід з емуляції</string>
<string name="emulation_done">Готово</string>
- <string name="emulation_fps_counter">Лічильник FPS</string>
- <string name="emulation_toggle_controls">Перемикання керування</string>
- <string name="emulation_rel_stick_center">Відносний центр стіка</string>
- <string name="emulation_dpad_slide">Слайд хрестовиною</string>
- <string name="emulation_haptics">Тактильний зворотний зв\'язок</string>
- <string name="emulation_show_overlay">Показати оверлей</string>
- <string name="emulation_toggle_all">Перемкнути все</string>
- <string name="emulation_control_adjust">Налаштувати оверлей</string>
<string name="emulation_control_scale">Масштаб</string>
<string name="emulation_control_opacity">Непрозорість</string>
- <string name="emulation_touch_overlay_reset">Скинути оверлей</string>
- <string name="emulation_touch_overlay_edit">Змінити оверлей</string>
- <string name="emulation_pause">Пауза емуляції</string>
- <string name="emulation_unpause">Відновлення емуляції</string>
- <string name="emulation_input_overlay">Налаштування оверлея</string>
-
- <string name="load_settings">Завантаження налаштувань...</string>
-
- <!-- Software keyboard -->
- <string name="software_keyboard">Віртуальна клавіатура</string>
-
<!-- Errors and warnings -->
<string name="abort_button">Перервати</string>
<string name="continue_button">Продовжити</string>
@@ -226,7 +183,6 @@
<string name="fatal_error">Фатальна помилка</string>
<string name="fatal_error_message">Сталася фатальна помилка. Перевірте журнал для отримання докладної інформації.\nПродовження емуляції може призвести до збоїв і помилок.</string>
<string name="performance_warning">Вимкнення цього налаштування значно знизить продуктивність емуляції! Для досягнення найкращих результатів рекомендується залишити це налаштування увімкненим.</string>
-
<!-- Region Names -->
<string name="region_japan">Японія</string>
<string name="region_usa">США</string>
@@ -236,8 +192,7 @@
<string name="region_korea">Корея</string>
<string name="region_taiwan">Тайвань</string>
- <!-- Language Names -->
-
+ <string name="memory_gigabyte">GB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
<string name="renderer_none">Вимкнено</string>
@@ -274,22 +229,18 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <string name="screen_layout_auto">Авто</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">За замовчуванням (16:9)</string>
<string name="ratio_force_four_three">Змусити 4:3</string>
<string name="ratio_force_twenty_one_nine">Змусити 21:9</string>
<string name="ratio_force_sixteen_ten">Змусити 16:10</string>
- <string name="ratio_stretch">Розтягнути до вікна</string>
-
<!-- CPU Accuracy -->
<string name="cpu_accuracy_accurate">Точно</string>
<string name="cpu_accuracy_unsafe">Небезпечно</string>
<string name="cpu_accuracy_paranoid">Параноїк (повільно)</string>
- <!-- Gamepad Buttons -->
- <string name="gamepad_d_pad">Кнопки напрямків</string>
- <string name="gamepad_left_stick">Лівий міні-джойстик</string>
- <string name="gamepad_right_stick">Правий міні-джойстик</string>
<string name="gamepad_home">Home</string>
<string name="gamepad_screenshot">Знімок екрану</string>
@@ -297,19 +248,16 @@
<string name="preparing_shaders">Підготовка шейдерів</string>
<string name="building_shaders">Побудова шейдерів</string>
- <!-- Theme options -->
- <string name="change_app_theme">Змінити тему застосунку</string>
<string name="theme_default">За замовчуванням</string>
<string name="theme_material_you">Material You</string>
- <!-- Theme Modes -->
- <string name="change_theme_mode">Змінити режим теми</string>
<string name="theme_mode_follow_system">Системна</string>
<string name="theme_mode_light">Світла</string>
<string name="theme_mode_dark">Темна</string>
- <!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">Використовувати чорне тло</string>
<string name="use_black_backgrounds_description">У разі використання темної теми застосовуйте чорне тло.</string>
-</resources>
+ <string name="mute">Вимкнути звук</string>
+ <string name="unmute">Увімкнути звук</string>
+
+ </resources>
diff --git a/src/android/app/src/main/res/values-vi/strings.xml b/src/android/app/src/main/res/values-vi/strings.xml
new file mode 100644
index 000000000..f977db3a2
--- /dev/null
+++ b/src/android/app/src/main/res/values-vi/strings.xml
@@ -0,0 +1,340 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
+
+ <string name="app_disclaimer">Phần mềm này sẽ chạy các game cho máy chơi game Nintendo Switch. Không có title games hoặc keys được bao gồm.&lt;br /&gt;&lt;br /&gt;Trước khi bạn bắt đầu, hãy tìm tập tin <![CDATA[<b> prod.keys </b>]]> trên bộ nhớ thiết bị của bạn.&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Tìm hiểu thêm</a>]]></string>
+ <string name="emulation_notification_channel_name">Giả lập đang chạy</string>
+ <string name="emulation_notification_channel_description">Hiển thị thông báo liên tục khi giả lập đang chạy.</string>
+ <string name="emulation_notification_running">yuzu đang chạy</string>
+ <string name="notice_notification_channel_name">Thông báo và lỗi</string>
+ <string name="notice_notification_channel_description">Hiển thị thông báo khi có sự cố xảy ra.</string>
+ <string name="notification_permission_not_granted">Ứng dụng không được cấp quyền thông báo!</string>
+
+ <!-- Setup strings -->
+ <string name="welcome">Chào mừng!</string>
+ <string name="welcome_description">Tìm hiểu cách cài đặt &lt;b>yuzu&lt;/b> và bắt đầu giả lập.</string>
+ <string name="get_started">Bắt đầu</string>
+ <string name="keys">Keys</string>
+ <string name="keys_description">Chọn tệp &lt;b>prod.keys&lt;/b> của bạn bằng nút bên dưới.</string>
+ <string name="select_keys">Chọn Keys</string>
+ <string name="games">Game</string>
+ <string name="games_description">Chọn thư mục &lt;b>Game&lt;/b> của bạn bằng nút bên dưới.</string>
+ <string name="done">Hoàn thành</string>
+ <string name="done_description">Tất cả đã hoàn tất.\nHãy tận hưởng các game của bạn!</string>
+ <string name="text_continue">Tiếp tục</string>
+ <string name="next">Tiếp theo</string>
+ <string name="back">Trở lại</string>
+ <string name="add_games">Thêm Game</string>
+ <string name="add_games_description">Chọn thư mục game của bạn</string>
+ <!-- Home strings -->
+ <string name="home_games">Game</string>
+ <string name="home_search">Tìm kiếm</string>
+ <string name="home_settings">Cài đặt</string>
+ <string name="empty_gamelist">Không tìm thấy tập tin hoặc chưa có thư mục game nào được chọn.</string>
+ <string name="search_and_filter_games">Tìm và lọc game</string>
+ <string name="select_games_folder">Chọn thư mục game</string>
+ <string name="select_games_folder_description">Cho phép yuzu thêm vào danh sách game</string>
+ <string name="add_games_warning">Bỏ qua việc lựa chọn thư mục game?</string>
+ <string name="add_games_warning_description">Game sẽ không hiển thị trong danh sách nếu một thư mục không được chọn.</string>
+ <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
+ <string name="home_search_games">Tìm kiếm game</string>
+ <string name="games_dir_selected">Thư mục game đã được chọn</string>
+ <string name="install_prod_keys">Cài đặt prod.keys</string>
+ <string name="install_prod_keys_description">Yêu cầu để giải mã các game bán lẻ</string>
+ <string name="install_prod_keys_warning">Bỏ qua việc thêm keys?</string>
+ <string name="install_prod_keys_warning_description">Cần có keys hợp lệ để giả lập các game bán lẻ. Chỉ có các ứng dụng homebrew có thể vận hành nếu bạn tiếp tục.</string>
+ <string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
+ <string name="notifications">Thông báo</string>
+ <string name="notifications_description">Cấp quyền thông báo bằng nút bên dưới.</string>
+ <string name="give_permission">Cấp quyền</string>
+ <string name="notification_warning">Bỏ qua việc cấp quyền thông báo?</string>
+ <string name="notification_warning_description">yuzu sẽ không thể gửi những thông báo quan trọng đến bạn.</string>
+ <string name="permission_denied">Đã từ chối cấp quyền</string>
+ <string name="permission_denied_description">Bạn từ chối cấp quyền này quá nhiều lần và giờ bạn phải cấp quyền thủ công trong cài đặt máy.</string>
+ <string name="about">Thông tin</string>
+ <string name="about_description">Phiên bản, đóng góp và những thứ khác</string>
+ <string name="warning_help">Trợ giúp</string>
+ <string name="warning_skip">Bỏ qua</string>
+ <string name="warning_cancel">Hủy bỏ</string>
+ <string name="install_amiibo_keys">Cài đặt keys Amiibo</string>
+ <string name="install_amiibo_keys_description">Cần thiết để dùng Amiibo trong game</string>
+ <string name="invalid_keys_file">Tệp keys không hợp lệ đã được chọn</string>
+ <string name="install_keys_success">Cài đặt keys thành công</string>
+ <string name="reading_keys_failure">Lỗi đọc keys mã hóa</string>
+ <string name="install_prod_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .keys và thử lại.</string>
+ <string name="install_amiibo_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .bin và thử lại.</string>
+ <string name="invalid_keys_error">Keys mã hoá không hợp lệ</string>
+ <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
+ <string name="install_keys_failure_description">Tệp đã chọn sai hoặc hỏng. Vui lòng trích xuất lại keys của bạn.</string>
+ <string name="install_gpu_driver">Cài đặt driver GPU</string>
+ <string name="install_gpu_driver_description">Cài đặt driver thay thế để có thể có hiệu suất tốt và chính xác hơn</string>
+ <string name="advanced_settings">Cài đặt nâng cao</string>
+ <string name="settings_description">Cấu hình cài đặt giả lập</string>
+ <string name="search_recently_played">Đã chơi gần đây</string>
+ <string name="search_recently_added">Đã thêm gần đây</string>
+ <string name="search_retail">Bán lẻ</string>
+ <string name="search_homebrew">Homebrew</string>
+ <string name="open_user_folder">Mở thư mục yuzu</string>
+ <string name="open_user_folder_description">Quản lý tệp nội bộ của yuzu</string>
+ <string name="theme_and_color_description">Thay đổi giao diện ứng dụng</string>
+ <string name="no_file_manager">Không tìm thấy trình quản lý tập tin</string>
+ <string name="notification_no_directory_link">Không thể mở thư mục yuzu</string>
+ <string name="notification_no_directory_link_description">Vui lòng xác định thư mục người dùng với bảng điều khiển bên của trình quản lý tệp thủ công.</string>
+ <string name="manage_save_data">Quản lý dữ liệu save</string>
+ <string name="manage_save_data_description">Đã tìm thấy dữ liệu save. Vui lòng chọn một tuỳ chọn bên dưới.</string>
+ <string name="import_export_saves_description">Nhập hoặc xuất tệp save</string>
+ <string name="save_file_imported_success">Nhập thành công</string>
+ <string name="save_file_invalid_zip_structure">Cấu trúc thư mục save không hợp lệ</string>
+ <string name="save_file_invalid_zip_structure_description">Tên thư mục con đầu tiên phải là ID title của game.</string>
+ <string name="import_saves">Nhập</string>
+ <string name="export_saves">Xuất</string>
+ <string name="install_firmware">Cài đặt firmware</string>
+ <string name="install_firmware_description">Firmware phải được đặt trong một tập tin nén ZIP và cần thiết để khởi chạy một số game</string>
+ <string name="firmware_installing">Đang cài đặt firmware</string>
+ <string name="firmware_installed_success">Cài đặt firmware thành công</string>
+ <string name="firmware_installed_failure">Cài đặt firmware thất bại</string>
+ <string name="share_log">Chia sẻ nhật ký gỡ lỗi</string>
+ <string name="share_log_description">Chia sẻ tập tin nhật ký của yuzu để gỡ lỗi vấn đề</string>
+ <string name="share_log_missing">Không tìm thấy tập tin nhật ký</string>
+ <string name="install_game_content">Cài đặt nội dung game</string>
+ <string name="install_game_content_description">Cài đặt cập nhật game hoặc DLC</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <!-- About screen strings -->
+ <string name="gaia_is_not_real">Gaia không có thật</string>
+ <string name="copied_to_clipboard">Đã sao chép vào bộ nhớ tạm</string>
+ <string name="about_app_description">Một giả lập Switch mã nguồn mở</string>
+ <string name="contributors">Người đóng góp</string>
+ <string name="contributors_description">Được làm với \u2764 từ nhóm yuzu</string>
+ <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Các dự án làm cho yuzu trên Android trở thành điều có thể</string>
+ <string name="build">Dựng</string>
+ <string name="support_link">https://discord.gg/u77vRWY</string>
+ <string name="website_link">https://yuzu-emu.org/</string>
+ <string name="github_link">https://github.com/yuzu-emu</string>
+
+ <!-- Early access upgrade strings -->
+ <string name="early_access">Early Access</string>
+ <string name="get_early_access">Tải Early Access</string>
+ <string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
+ <string name="get_early_access_description">Các tính năng tiên tiến, truy cập sớm các bản cập nhật và nhiều hơn nữa</string>
+ <string name="early_access_benefits">Lợi ích của Early Access</string>
+ <string name="cutting_edge_features">Tính năng tiên tiến</string>
+ <string name="early_access_updates">Truy cập sớm các bản cập nhật</string>
+ <string name="no_manual_installation">Không có cài đặt thủ công</string>
+ <string name="prioritized_support">Ưu tiên hỗ trợ</string>
+ <string name="helping_game_preservation">Hỗ trợ bảo tồn game</string>
+ <string name="our_eternal_gratitude">Sự biết ơn vô hạn của chúng tôi</string>
+ <string name="are_you_interested">Bạn có thấy hứng thú không?</string>
+
+ <!-- General settings strings -->
+ <string name="frame_limit_enable">Giới hạn tốc độ</string>
+ <string name="frame_limit_enable_description">Giới hạn tốc độ giả lập ở một phần trăm cụ thể của tốc độ bình thường.</string>
+ <string name="frame_limit_slider">Giới hạn phần trăm tốc độ</string>
+ <string name="frame_limit_slider_description">Xác định phần trăm để giới hạn tốc độ giả lập. 100% là tốc độ bình thường. Giá trị cao hơn hoặc thấp hơn sẽ tăng hoặc giảm giới hạn tốc độ.</string>
+ <string name="cpu_accuracy">Độ chính xác CPU</string>
+ <!-- System settings strings -->
+ <string name="use_docked_mode">Chế độ docked</string>
+ <string name="use_docked_mode_description">Tăng độ phân giải, giảm hiệu suất. Chế độ handheld được sử dụng khi tắt, giảm độ phân giải và tăng hiệu suất.</string>
+ <string name="emulated_region">Khu vực giả lập</string>
+ <string name="emulated_language">Ngôn ngữ giả lập</string>
+ <string name="select_rtc_date">Chọn ngày RTC</string>
+ <string name="select_rtc_time">Chọn giờ RTC</string>
+ <string name="use_custom_rtc">RTC tuỳ chỉnh</string>
+ <string name="use_custom_rtc_description">Cho phép bạn thiết lập một đồng hồ thời gian thực tùy chỉnh riêng biệt so với thời gian hệ thống hiện tại.</string>
+ <string name="set_custom_rtc">Thiết lập RTC tùy chỉnh</string>
+
+ <!-- Graphics settings strings -->
+ <string name="renderer_accuracy">Mức độ chính xác</string>
+ <string name="renderer_resolution">Độ phân giải (Handheld/Docked)</string>
+ <string name="renderer_vsync">Chế độ VSync</string>
+ <string name="renderer_aspect_ratio">Tỉ lệ khung hình</string>
+ <string name="renderer_scaling_filter">Bộ lọc điều chỉnh cửa sổ</string>
+ <string name="renderer_anti_aliasing">Phương pháp khử răng cưa</string>
+ <string name="renderer_force_max_clock">Buộc chạy ở xung nhịp tối đa (chỉ cho Adreno)</string>
+ <string name="renderer_force_max_clock_description">Buộc GPU hoạt động ở xung nhịp tối đa có thể (ràng buộc nhiệt độ vẫn sẽ được áp dụng).</string>
+ <string name="renderer_asynchronous_shaders">Dùng các shader bất đồng bộ</string>
+ <string name="renderer_asynchronous_shaders_description">Biên dịch các shader bất đồng bộ, giảm tình trạng giật lag nhưng có thể gây ra các lỗi.</string>
+ <string name="renderer_reactive_flushing">Dùng xả tương ứng</string>
+ <string name="renderer_reactive_flushing_description">Cải thiện độ chính xác kết xuất trong một số game nhưng đồng thời giảm hiệu suất.</string>
+ <string name="use_disk_shader_cache">Lưu bộ nhớ đệm shader trên ổ cứng</string>
+ <string name="use_disk_shader_cache_description">Giảm tình trạng giật lag bằng cách lưu trữ và tải các shader được tạo ra nội bộ.</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">Gỡ lỗi đồ hoạ</string>
+ <string name="renderer_debug_description">Đặt API đồ họa vào chế độ gỡ lỗi chậm.</string>
+ <string name="audio_volume">Âm lượng</string>
+ <string name="audio_volume_description">Xác định âm lượng của đầu ra âm thanh.</string>
+
+ <!-- Miscellaneous -->
+ <string name="slider_default">Mặc định</string>
+ <string name="ini_saved">Cài đặt đã lưu</string>
+ <string name="gameid_saved">Cài đặt đã lưu cho %1$s</string>
+ <string name="error_saving">Lỗi khi lưu %1$s.ini: %2$s</string>
+ <string name="loading">Đang tải...</string>
+ <string name="reset_setting_confirmation">Bạn có muốn đặt lại cài đặt này về giá trị mặc định không?</string>
+ <string name="reset_to_default">Đặt lại về mặc định</string>
+ <string name="reset_all_settings">Bạn có muốn đặt lại tất cả các cài đặt về giá trị mặc định không?</string>
+ <string name="reset_all_settings_description">Tất cả các cài đặt nâng cao sẽ được đặt lại về cấu hình mặc định. Điều này không thể hoàn tác.</string>
+ <string name="settings_reset">Cài đặt đã được đặt lại</string>
+ <string name="close">Đóng</string>
+ <string name="learn_more">Tìm hiểu thêm</string>
+ <string name="auto">Tự động</string>
+ <string name="submit">Gửi</string>
+ <string name="string_null">Null</string>
+ <string name="string_import">Nhập</string>
+ <string name="export">Xuất</string>
+ <!-- GPU driver installation -->
+ <string name="select_gpu_driver">Chọn driver GPU</string>
+ <string name="select_gpu_driver_title">Bạn có muốn thay thế driver GPU hiện tại không?</string>
+ <string name="select_gpu_driver_install">Cài đặt</string>
+ <string name="select_gpu_driver_default">Mặc định</string>
+ <string name="select_gpu_driver_use_default">Dùng driver GPU mặc định</string>
+ <string name="select_gpu_driver_error">Driver không hợp lệ đã được chọn, dùng mặc định hệ thống!</string>
+ <string name="system_gpu_driver">Driver GPU hệ thống</string>
+ <string name="installing_driver">Đang cài đặt driver...</string>
+
+ <!-- Preferences Screen -->
+ <string name="preferences_settings">Cài đặt</string>
+ <string name="preferences_general">Chung</string>
+ <string name="preferences_system">Hệ thống</string>
+ <string name="preferences_graphics">Đồ hoạ</string>
+ <string name="preferences_audio">Âm thanh</string>
+ <string name="preferences_theme">Chủ đề và màu sắc</string>
+ <string name="preferences_debug">Gỡ lỗi</string>
+
+ <!-- ROM loading errors -->
+ <string name="loader_error_encrypted">ROM của bạn đã bị mã hoá</string>
+ <string name="loader_error_encrypted_keys_description"><![CDATA[Vui lòng đảm bảo tệp <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> đã được cài đặt để các game có thể được giải mã.]]></string>
+ <string name="loader_error_video_core">Đã xảy ra lỗi khi khởi tạo lõi video</string>
+ <string name="loader_error_video_core_description">Việc này thường do driver GPU không tương thích. Cài đặt một driver GPU tùy chỉnh có thể giải quyết vấn đề này.</string>
+ <string name="loader_error_invalid_format">Không thể nạp ROM</string>
+ <string name="loader_error_file_not_found">Tệp ROM không tồn tại</string>
+
+ <!-- Emulation Menu -->
+ <string name="emulation_exit">Thoát giả lập</string>
+ <string name="emulation_done">Hoàn thành</string>
+ <string name="emulation_fps_counter">Bộ đếm FPS</string>
+ <string name="emulation_toggle_controls">Chuyển đổi điều khiển</string>
+ <string name="emulation_rel_stick_center">Trung tâm nút cần xoay tương đối</string>
+ <string name="emulation_dpad_slide">Trượt D-pad</string>
+ <string name="emulation_haptics">Chạm haptics</string>
+ <string name="emulation_show_overlay">Hiện lớp phủ</string>
+ <string name="emulation_toggle_all">Chuyển đổi tất cả</string>
+ <string name="emulation_control_adjust">Điều chỉnh lớp phủ</string>
+ <string name="emulation_control_scale">Tỉ lệ thu phóng</string>
+ <string name="emulation_control_opacity">Độ mờ</string>
+ <string name="emulation_touch_overlay_reset">Đặt lại lớp phủ</string>
+ <string name="emulation_touch_overlay_edit">Chỉnh sửa lớp phủ</string>
+ <string name="emulation_pause">Tạm đừng giả lập</string>
+ <string name="emulation_unpause">Tiếp tục giả lập</string>
+ <string name="emulation_input_overlay">Tuỳ chọn lớp phủ</string>
+
+ <string name="load_settings">Đang tải cài đặt...</string>
+
+ <!-- Software keyboard -->
+ <string name="software_keyboard">Bàn phím mềm</string>
+
+ <!-- Errors and warnings -->
+ <string name="abort_button">Hủy bỏ</string>
+ <string name="continue_button">Tiếp tục</string>
+ <string name="system_archive_not_found">Không tìm thấy bản lưu trữ của hệ thống</string>
+ <string name="system_archive_not_found_message">%s bị thiếu. Vui lòng trích xuất các bản lưu trữ hệ thống của bạn.\nNếu chạy tiếp giả lập có thể bị crash và lỗi.</string>
+ <string name="system_archive_general">Một bản lưu trữ của hệ thống</string>
+ <string name="save_load_error">Lỗi Lưu/Tải</string>
+ <string name="fatal_error">Lỗi nghiêm trọng</string>
+ <string name="fatal_error_message">Đã xảy ra lỗi nghiêm trọng. Kiểm tra nhật ký để biết thêm chi tiết.\nNếu chạy tiếp giả lập có thể bị crash và lỗi.</string>
+ <string name="performance_warning">Tắt cài đặt này sẽ làm giảm đáng kể hiệu suất giả lập! Để có trải nghiệm tốt nhất, bạn nên bật cài đặt này.</string>
+ <!-- Region Names -->
+ <string name="region_japan">Nhật Bản</string>
+ <string name="region_usa">Hoa Kỳ</string>
+ <string name="region_europe">Châu Âu</string>
+ <string name="region_australia">Úc</string>
+ <string name="region_china">Trung Quốc</string>
+ <string name="region_korea">Hàn Quốc</string>
+ <string name="region_taiwan">Đài Loan</string>
+
+ <string name="memory_gigabyte">GB</string>
+ <!-- Renderer APIs -->
+ <string name="renderer_vulkan">Vulkan</string>
+ <string name="renderer_none">Không có</string>
+
+ <!-- Renderer Accuracy -->
+ <string name="renderer_accuracy_normal">Bình thường</string>
+ <string name="renderer_accuracy_high">Cao</string>
+ <string name="renderer_accuracy_extreme">Cực đại (Chậm)</string>
+
+ <!-- Resolutions -->
+ <string name="resolution_half">0.5X (360p/540p)</string>
+ <string name="resolution_three_quarter">0.75X (540p/810p)</string>
+ <string name="resolution_one">1X (720p/1080p)</string>
+ <string name="resolution_two">2X (1440p/2160p) (Chậm)</string>
+ <string name="resolution_three">3X (2160p/3240p) (Chậm)</string>
+ <string name="resolution_four">4X (2880p/4320p) (Chậm)</string>
+
+ <!-- Renderer VSync -->
+ <string name="renderer_vsync_immediate">Immediate (Tắt)</string>
+ <string name="renderer_vsync_mailbox">Mailbox</string>
+ <string name="renderer_vsync_fifo">FIFO (Bật)</string>
+ <string name="renderer_vsync_fifo_relaxed">FIFO Relaxed</string>
+
+ <!-- Scaling Filters -->
+ <string name="scaling_filter_nearest_neighbor">Nearest Neighbor</string>
+ <string name="scaling_filter_bilinear">Bilinear</string>
+ <string name="scaling_filter_bicubic">Bicubic</string>
+ <string name="scaling_filter_gaussian">Gaussian</string>
+ <string name="scaling_filter_scale_force">ScaleForce</string>
+ <string name="scaling_filter_fsr">AMD FidelityFX™ Super Resolution</string>
+
+ <!-- Anti-Aliasing -->
+ <string name="anti_aliasing_none">Không có</string>
+ <string name="anti_aliasing_fxaa">FXAA</string>
+ <string name="anti_aliasing_smaa">SMAA</string>
+
+ <string name="screen_layout_auto">Tự động</string>
+
+ <!-- Aspect Ratios -->
+ <string name="ratio_default">Mặc định (16:9)</string>
+ <string name="ratio_force_four_three">Dùng 4:3</string>
+ <string name="ratio_force_twenty_one_nine">Dùng 21:9</string>
+ <string name="ratio_force_sixteen_ten">Dùng 16:10</string>
+ <string name="ratio_stretch">Mở rộng đến cửa sổ</string>
+
+ <!-- CPU Accuracy -->
+ <string name="cpu_accuracy_accurate">Chính xác</string>
+ <string name="cpu_accuracy_unsafe">Không an toàn</string>
+ <string name="cpu_accuracy_paranoid">Paranoid (Chậm)</string>
+
+ <!-- Gamepad Buttons -->
+ <string name="gamepad_d_pad">D-pad</string>
+ <string name="gamepad_left_stick">Cần trái</string>
+ <string name="gamepad_right_stick">Cần phải</string>
+ <string name="gamepad_home">Home</string>
+ <string name="gamepad_screenshot">Ảnh chụp màn hình</string>
+
+ <!-- Disk shader cache -->
+ <string name="preparing_shaders">Đang chuẩn bị shader</string>
+ <string name="building_shaders">Đang đựng shader</string>
+
+ <!-- Theme options -->
+ <string name="change_app_theme">Thay đổi chủ đề ứng dụng</string>
+ <string name="theme_default">Mặc định</string>
+ <string name="theme_material_you">Material You</string>
+
+ <!-- Theme Modes -->
+ <string name="change_theme_mode">Thay đổi chủ đề</string>
+ <string name="theme_mode_follow_system">Theo hệ thống</string>
+ <string name="theme_mode_light">Sáng</string>
+ <string name="theme_mode_dark">Tối</string>
+
+ <!-- Black backgrounds theme -->
+ <string name="use_black_backgrounds">Nền đen</string>
+ <string name="use_black_backgrounds_description">Khi sử dụng chủ đề tối, hãy áp dụng nền đen.</string>
+
+ <string name="mute">Tắt tiếng</string>
+ <string name="unmute">Bật tiếng</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">Giấy phép</string>
+ <string name="license_fidelityfx_fsr_description">Upscaling chất lượng cao từ AMD</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml
index c0e885751..13455564f 100644
--- a/src/android/app/src/main/res/values-zh-rCN/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">此软件可以运行 Nintendo Switch 游戏,但不包含任何游戏和密钥文件。&lt;br /&gt;&lt;br /&gt;在开始前,请找到放置于设备存储中的 <![CDATA[<b> prod.keys </b>]]> 文件。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">了解更多</a>]]></string>
<string name="emulation_notification_channel_name">正在进行模拟</string>
@@ -17,7 +17,7 @@
<string name="keys_description">使用下方的按钮来选择你的 &lt;b>prod.keys&lt;/b> 文件。</string>
<string name="select_keys">选择密钥文件</string>
<string name="games">游戏</string>
- <string name="games_description">使用下方的按钮选择你的 &lt;b>游戏&lt;/b> 文件夹。</string>
+ <string name="games_description">使用下方的按钮选择你的&lt;b>游戏&lt;/b>文件夹。</string>
<string name="done">完成</string>
<string name="done_description">你完成了全部设置。\n玩的开心!</string>
<string name="text_continue">继续</string>
@@ -25,6 +25,7 @@
<string name="back">上一步</string>
<string name="add_games">添加游戏</string>
<string name="add_games_description">选择你的游戏文件夹</string>
+ <string name="step_complete">完成!</string>
<!-- Home strings -->
<string name="home_games">游戏</string>
@@ -38,6 +39,7 @@
<string name="add_games_warning_description">如果未选择游戏文件夹,游戏将不会显示在游戏列表中。</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">搜索游戏</string>
+ <string name="search_settings">搜索设置</string>
<string name="games_dir_selected">已选择游戏文件夹</string>
<string name="install_prod_keys">安装 prod.keys 文件</string>
<string name="install_prod_keys_description">需要密钥文件来解密游戏</string>
@@ -61,12 +63,15 @@
<string name="invalid_keys_file">选择的密钥文件无效</string>
<string name="install_keys_success">密钥文件已成功安装</string>
<string name="reading_keys_failure">读取加密密钥时出错</string>
+ <string name="install_prod_keys_failure_extension_description">请确保您的密钥文件扩展名为 .keys 并重试。</string>
+ <string name="install_amiibo_keys_failure_extension_description">请确保您的密钥文件扩展名为 .bin 并重试。</string>
<string name="invalid_keys_error">无效的加密密钥</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">选择的密钥文件不正确或已损坏。请重新转储密钥文件。</string>
<string name="install_gpu_driver">安装 GPU 驱动</string>
<string name="install_gpu_driver_description">安装替代的驱动程序以获得更好的性能和精度</string>
<string name="advanced_settings">高级选项</string>
+ <string name="advanced_settings_game">高级选项: %1$s</string>
<string name="settings_description">更改模拟器设置</string>
<string name="search_recently_played">最近游玩</string>
<string name="search_recently_added">最近添加</string>
@@ -86,6 +91,33 @@
<string name="save_file_invalid_zip_structure_description">第一个子文件夹名称必须为当前游戏的 ID。</string>
<string name="import_saves">导入</string>
<string name="export_saves">导出</string>
+ <string name="install_firmware">安装固件</string>
+ <string name="install_firmware_description">固件文件必须为 zip 格式,启动某些游戏时必需</string>
+ <string name="firmware_installing">正在安装固件</string>
+ <string name="firmware_installed_success">固件已成功安装</string>
+ <string name="firmware_installed_failure">固件安装失败</string>
+ <string name="firmware_installed_failure_description">请确保固件 nca 文件位于 zip 压缩包的根目录,然后重试。</string>
+ <string name="share_log">分享调试日志</string>
+ <string name="share_log_description">分享 yuzu 日志文件以便调试</string>
+ <string name="share_log_missing">未找到日志文件</string>
+ <string name="install_game_content">安装游戏附加内容</string>
+ <string name="install_game_content_description">安装游戏更新及 DLC</string>
+ <string name="installing_game_content">安装中...</string>
+ <string name="install_game_content_failure">向 NAND 安装文件时失败</string>
+ <string name="install_game_content_failure_description">请确保附加内容的有效性,并且 prod.keys 密钥文件已安装。</string>
+ <string name="install_game_content_failure_base">为避免产生冲突,此功能不能用于安装游戏本体。</string>
+ <string name="install_game_content_failure_file_extension">只有 NSP 或 XCI 格式的附加内容可以安装。请确保您的游戏附加内容是有效的。</string>
+ <string name="install_game_content_failed_count">%1$d 安装出错</string>
+ <string name="install_game_content_success">游戏附加内容已成功安装</string>
+ <string name="install_game_content_success_install">%1$d 安装成功</string>
+ <string name="install_game_content_success_overwrite">%1$d 覆盖安装成功</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">不支持自定义驱动</string>
+ <string name="custom_driver_not_supported_description">此设备不支持自定义驱动。\n请之后再访问此项,查看是否已为此设备添加支持。</string>
+ <string name="manage_yuzu_data">管理 yuzu 数据</string>
+ <string name="manage_yuzu_data_description">导入/导出固件、密钥、用户数据及其他。</string>
+ <string name="share_save_file">分享存档文件</string>
+ <string name="export_save_failed">导出存档文件失败</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia 不真实</string>
@@ -94,14 +126,25 @@
<string name="contributors">贡献者</string>
<string name="contributors_description">使用来自 yuzu 团队的 \u2764 制作</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">Android 版 yuzu 离不开这些项目的支持</string>
<string name="build">构建版本</string>
+ <string name="user_data">用户数据</string>
+ <string name="user_data_description">导入/导出应用程序所有数据。\n\n导入用户数据时,将删除当前所有的用户数据!</string>
+ <string name="exporting_user_data">正在导出用户数据...</string>
+ <string name="importing_user_data">正在导入用户数据...</string>
+ <string name="import_user_data">导入用户数据</string>
+ <string name="invalid_yuzu_backup">无效的 yuzu 备份</string>
+ <string name="user_data_export_success">导出用户数据成功</string>
+ <string name="user_data_import_success">导入用户数据成功</string>
+ <string name="user_data_export_cancelled">已取消导出数据</string>
+ <string name="user_data_import_failed_description">请确保用户数据文件夹位于 zip 压缩包的根目录,并在 config/config.ini 路径中包含配置文件,然后重试。</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
<!-- Early access upgrade strings -->
<string name="early_access">抢先体验</string>
- <string name="get_early_access">取得抢先体验</string>
+ <string name="get_early_access">获取抢先体验!</string>
<string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
<string name="get_early_access_description">最新的功能、抢先更新、以及更多</string>
<string name="early_access_benefits">抢先体验的权益</string>
@@ -109,33 +152,34 @@
<string name="early_access_updates">抢先更新</string>
<string name="no_manual_installation">无需手动安装</string>
<string name="prioritized_support">优先支持</string>
- <string name="helping_game_preservation">帮助保留游戏</string>
+ <string name="helping_game_preservation">帮助保留游玩历史</string>
<string name="our_eternal_gratitude">我们真诚的感激</string>
<string name="are_you_interested">您对此感兴趣吗?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">启用运行速度限制</string>
- <string name="frame_limit_enable_description">启用后,模拟速度将限制在正常运行速度的指定百分比。</string>
+ <string name="frame_limit_enable">运行速度限制</string>
+ <string name="frame_limit_enable_description">将运行速度限制为正常速度的指定百分比。</string>
<string name="frame_limit_slider">限制速度百分比</string>
- <string name="frame_limit_slider_description">指定限制模拟速度的百分比。预设为 100%,此时模拟速度将被限制为标准速度。更高或更低的值将增加或降低速度限制上限。</string>
+ <string name="frame_limit_slider_description">指定限制运行速度的百分比。100% 为正常速度。更高或更低的值将增加或降低速度限制上限。</string>
<string name="cpu_accuracy">CPU 精度</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
<string name="use_docked_mode">主机模式</string>
- <string name="use_docked_mode_description">以主机模式进行模拟,牺牲性能并提高画面分辨率。</string>
+ <string name="use_docked_mode_description">提高分辨率,但降低性能。禁用此项时使用掌机模式,降低分辨率并提高性能。</string>
<string name="emulated_region">模拟区域</string>
<string name="emulated_language">模拟语言</string>
<string name="select_rtc_date">选择日期</string>
<string name="select_rtc_time">选择时间</string>
- <string name="use_custom_rtc">启用自定义系统时钟</string>
- <string name="use_custom_rtc_description">此选项允许您设置与目前系统时间相独立的自定义系统时钟</string>
- <string name="set_custom_rtc">设置自定义系统时钟</string>
+ <string name="use_custom_rtc">自定义系统时间</string>
+ <string name="use_custom_rtc_description">此选项允许您设置与目前系统时间相独立的自定义系统时钟。</string>
+ <string name="set_custom_rtc">设置自定义系统时间</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">精度等级</string>
- <string name="renderer_resolution">分辨率</string>
+ <string name="renderer_resolution">分辨率 (掌机模式/主机模式)</string>
<string name="renderer_vsync">垂直同步模式</string>
+ <string name="renderer_screen_layout">屏幕方向</string>
<string name="renderer_aspect_ratio">屏幕纵横比</string>
<string name="renderer_scaling_filter">窗口滤镜</string>
<string name="renderer_anti_aliasing">抗锯齿方式</string>
@@ -143,12 +187,23 @@
<string name="renderer_force_max_clock_description">强制 GPU 以最大时钟运行 (仍被温控限制)。</string>
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
<string name="renderer_asynchronous_shaders_description">异步编译着色器,减少卡顿,但可能引入故障。</string>
- <string name="renderer_debug">启用图形调试</string>
- <string name="renderer_debug_description">启用时,图形 API 将进入较慢的调试模式。</string>
- <string name="use_disk_shader_cache">使用磁盘着色器缓存</string>
- <string name="use_disk_shader_cache_description">将生成的着色器缓存于磁盘中并进行读取以减少卡顿。</string>
+ <string name="renderer_reactive_flushing">启用反应性刷新</string>
+ <string name="renderer_reactive_flushing_description">牺牲性能,提高某些游戏的渲染精度。</string>
+ <string name="use_disk_shader_cache">磁盘着色器缓存</string>
+ <string name="use_disk_shader_cache_description">将生成的着色器缓存于磁盘中并进行读取,以减少卡顿。</string>
+
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">CPU 调试</string>
+ <string name="cpu_debug_mode_description">将 CPU 设置为较慢的调试模式。</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">图形调试</string>
+ <string name="renderer_debug_description">将图形 API 设置为较慢的调试模式。</string>
+ <string name="fastmem">Fastmem</string>
<!-- Audio settings strings -->
+ <string name="audio_output_engine">输出引擎</string>
<string name="audio_volume">音量</string>
<string name="audio_volume_description">指定输出的音量。</string>
@@ -157,7 +212,9 @@
<string name="ini_saved">已保存设置</string>
<string name="gameid_saved">已保存 %1$s 的设置</string>
<string name="error_saving">保存 %1$s.ini 时出错: %2$s</string>
+ <string name="unimplemented_menu">未生效菜单</string>
<string name="loading">加载中…</string>
+ <string name="shutting_down">正在关闭…</string>
<string name="reset_setting_confirmation">您要将此设定重设为默认值吗?</string>
<string name="reset_to_default">恢复默认</string>
<string name="reset_all_settings">重置所有设置项?</string>
@@ -165,6 +222,14 @@
<string name="settings_reset">重设设置项</string>
<string name="close">关闭</string>
<string name="learn_more">了解更多</string>
+ <string name="auto">自动</string>
+ <string name="submit">提交</string>
+ <string name="string_null">无</string>
+ <string name="string_import">导入</string>
+ <string name="export">导出</string>
+ <string name="export_failed">导出失败</string>
+ <string name="import_failed">导入失败</string>
+ <string name="cancelling">取消中</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">选择 GPU 驱动程序</string>
@@ -172,6 +237,7 @@
<string name="select_gpu_driver_install">安装</string>
<string name="select_gpu_driver_default">系统默认</string>
<string name="select_gpu_driver_use_default">使用默认 GPU 驱动程序</string>
+ <string name="select_gpu_driver_error">选择的驱动程序无效,将使用系统默认的驱动程序!</string>
<string name="system_gpu_driver">系统 GPU 驱动程序</string>
<string name="installing_driver">正在安装驱动程序…</string>
@@ -182,10 +248,11 @@
<string name="preferences_graphics">图形</string>
<string name="preferences_audio">声音</string>
<string name="preferences_theme">主题和色彩</string>
+ <string name="preferences_debug">调试</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">您的 ROM 已加密</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[请参考指南重新转储你的<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">游戏卡带</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">已安装的游戏</a>。]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[请按照指南重新转储您的<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">游戏卡带</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">已安装的游戏</a>。]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[请确保 <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 文件已安装,使得游戏可以被解密。]]></string>
<string name="loader_error_video_core">初始化视频核心时发生错误</string>
<string name="loader_error_video_core_description">这通常由不兼容的 GPU 驱动程序造成,安装自定义 GPU 驱动程序可能解决此问题。</string>
@@ -226,6 +293,9 @@
<string name="fatal_error">致命错误</string>
<string name="fatal_error_message">发生致命错误,请查阅日志获取详细信息。\n继续模拟可能会造成崩溃和错误。</string>
<string name="performance_warning">关闭此项会显著降低模拟性能!建议您将此项保持为启用状态。</string>
+ <string name="device_memory_inadequate">设备 RAM: %1$s\n推荐 RAM: %2$s</string>
+ <string name="memory_formatted">%1$s%2$s</string>
+ <string name="no_game_present">当前没有可启动的游戏!</string>
<!-- Region Names -->
<string name="region_japan">日本</string>
@@ -236,7 +306,14 @@
<string name="region_korea">韩国</string>
<string name="region_taiwan">中国台湾</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">GB</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
@@ -274,6 +351,11 @@
<string name="anti_aliasing_fxaa">快速近似抗锯齿</string>
<string name="anti_aliasing_smaa">子像素形态学抗锯齿</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">横向大屏</string>
+ <string name="screen_layout_portrait">纵向屏幕</string>
+ <string name="screen_layout_auto">自动</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">默认 (16:9)</string>
<string name="ratio_force_four_three">强制 4:3</string>
@@ -303,13 +385,27 @@
<string name="theme_material_you">Material You</string>
<!-- Theme Modes -->
- <string name="change_theme_mode">主题模式</string>
+ <string name="change_theme_mode">更改主题模式</string>
<string name="theme_mode_follow_system">跟随系统</string>
<string name="theme_mode_light">浅色</string>
<string name="theme_mode_dark">深色</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
<string name="use_black_backgrounds">使用黑色背景</string>
<string name="use_black_backgrounds_description">使用深色主题时,套用黑色背景。</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">画中画</string>
+ <string name="picture_in_picture_description">模拟器位于后台时最小化窗口</string>
+ <string name="pause">暂停</string>
+ <string name="play">开始</string>
+ <string name="mute">静音</string>
+ <string name="unmute">取消静音</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">许可证</string>
+ <string name="license_fidelityfx_fsr_description">来自 AMD 的高品质画质升级</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml
index 4a21bf893..b8f468c68 100644
--- a/src/android/app/src/main/res/values-zh-rTW/strings.xml
+++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_disclaimer">此軟體可以執行 Nintendo Switch 主機遊戲,但不包含任何遊戲和金鑰。&lt;br /&gt;&lt;br /&gt;在您開始前,請找到放置於您的裝置儲存空間的 <![CDATA[<b> prod.keys </b>]]> 檔案。&lt;br /&gt;&lt;br /&gt;<![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">深入瞭解</a>]]></string>
<string name="emulation_notification_channel_name">模擬進行中</string>
@@ -25,6 +25,7 @@
<string name="back">上一步</string>
<string name="add_games">新增遊戲</string>
<string name="add_games_description">選取您的遊戲資料夾</string>
+ <string name="step_complete">完成!</string>
<!-- Home strings -->
<string name="home_games">遊戲</string>
@@ -33,11 +34,12 @@
<string name="empty_gamelist">找不到檔案,或者尚未選取遊戲目錄。</string>
<string name="search_and_filter_games">搜尋並篩選遊戲</string>
<string name="select_games_folder">選取遊戲資料夾</string>
- <string name="select_games_folder_description">一律允許 yuzu 填入遊戲清單</string>
+ <string name="select_games_folder_description">允許 yuzu 填入遊戲清單</string>
<string name="add_games_warning">跳過選取遊戲資料夾?</string>
<string name="add_games_warning_description">如果資料夾未選取,遊戲將不會顯示在遊戲清單。</string>
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
<string name="home_search_games">搜尋遊戲</string>
+ <string name="search_settings">搜索设置</string>
<string name="games_dir_selected">遊戲目錄已選取</string>
<string name="install_prod_keys">安裝 prod.keys</string>
<string name="install_prod_keys_description">需要解密零售遊戲</string>
@@ -60,13 +62,16 @@
<string name="install_amiibo_keys_description">需要在遊戲中使用 Amiibo</string>
<string name="invalid_keys_file">無效的金鑰檔案已選取</string>
<string name="install_keys_success">金鑰已成功安裝</string>
- <string name="reading_keys_failure">讀取加密金鑰時出現錯誤</string>
+ <string name="reading_keys_failure">讀取加密金鑰時發生錯誤</string>
+ <string name="install_prod_keys_failure_extension_description">驗證您的金鑰檔案是否具有 .keys 副檔名並再試一次。</string>
+ <string name="install_amiibo_keys_failure_extension_description">驗證您的金鑰檔案是否具有 .bin 副檔名並再試一次。</string>
<string name="invalid_keys_error">無效的加密金鑰</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">選取的檔案不正確或已損毀,請重新傾印您的金鑰。</string>
<string name="install_gpu_driver">安裝 GPU 驅動程式</string>
<string name="install_gpu_driver_description">安裝替代驅動程式以取得潛在的更佳效能或準確度</string>
<string name="advanced_settings">進階設定</string>
+ <string name="advanced_settings_game">高级选项: %1$s</string>
<string name="settings_description">進行模擬器設定</string>
<string name="search_recently_played">最近遊玩</string>
<string name="search_recently_added">最近新增</string>
@@ -86,6 +91,33 @@
<string name="save_file_invalid_zip_structure_description">首個子資料夾名稱必須為遊戲標題 ID。</string>
<string name="import_saves">匯入</string>
<string name="export_saves">匯出</string>
+ <string name="install_firmware">安裝韌體</string>
+ <string name="install_firmware_description">韌體必須為 ZIP 封存檔,將會用於部分遊戲的啟動</string>
+ <string name="firmware_installing">正在安裝韌體</string>
+ <string name="firmware_installed_success">韌體已成功安裝</string>
+ <string name="firmware_installed_failure">韌體安裝失敗</string>
+ <string name="firmware_installed_failure_description">请确保固件 nca 文件位于 zip 压缩包的根目录,然后重试。</string>
+ <string name="share_log">分享偵錯記錄</string>
+ <string name="share_log_description">分享 yuzu 的記錄檔以便對相關問題進行偵錯</string>
+ <string name="share_log_missing">找不到記錄檔</string>
+ <string name="install_game_content">安裝遊戲內容</string>
+ <string name="install_game_content_description">安裝遊戲更新或 DLC</string>
+ <string name="installing_game_content">安装中...</string>
+ <string name="install_game_content_failure">向 NAND 安装文件时失败</string>
+ <string name="install_game_content_failure_description">请确保附加内容的有效性,并且 prod.keys 密钥文件已安装。</string>
+ <string name="install_game_content_failure_base">为避免产生冲突,此功能不能用于安装游戏本体。</string>
+ <string name="install_game_content_failure_file_extension">只有 NSP 或 XCI 格式的附加内容可以安装。请确保您的游戏附加内容是有效的。</string>
+ <string name="install_game_content_failed_count">%1$d 安装出错</string>
+ <string name="install_game_content_success">游戏附加内容已成功安装</string>
+ <string name="install_game_content_success_install">%1$d 安装成功</string>
+ <string name="install_game_content_success_overwrite">%1$d 覆盖安装成功</string>
+ <string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
+ <string name="custom_driver_not_supported">不支持自定义驱动</string>
+ <string name="custom_driver_not_supported_description">此设备不支持自定义驱动。\n请之后再访问此项,查看是否已为此设备添加支持。</string>
+ <string name="manage_yuzu_data">管理 yuzu 数据</string>
+ <string name="manage_yuzu_data_description">导入/导出固件、密钥、用户数据及其他。</string>
+ <string name="share_save_file">分享存档文件</string>
+ <string name="export_save_failed">导出存档文件失败</string>
<!-- About screen strings -->
<string name="gaia_is_not_real">Gaia 不真實</string>
@@ -94,7 +126,18 @@
<string name="contributors">參與者</string>
<string name="contributors_description">使用來自 yuzu 團隊的 \u2764 製作</string>
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
+ <string name="licenses_description">這些專案使 yuzu Android 版成為可能</string>
<string name="build">組建</string>
+ <string name="user_data">用户数据</string>
+ <string name="user_data_description">导入/导出应用程序所有数据。\n\n导入用户数据时,将删除当前所有的用户数据!</string>
+ <string name="exporting_user_data">正在导出用户数据...</string>
+ <string name="importing_user_data">正在导入用户数据...</string>
+ <string name="import_user_data">导入用户数据</string>
+ <string name="invalid_yuzu_backup">无效的 yuzu 备份</string>
+ <string name="user_data_export_success">导出用户数据成功</string>
+ <string name="user_data_import_success">导入用户数据成功</string>
+ <string name="user_data_export_cancelled">已取消导出数据</string>
+ <string name="user_data_import_failed_description">请确保用户数据文件夹位于 zip 压缩包的根目录,并在 config/config.ini 路径中包含配置文件,然后重试。</string>
<string name="support_link">https://discord.gg/u77vRWY</string>
<string name="website_link">https://yuzu-emu.org/</string>
<string name="github_link">https://github.com/yuzu-emu</string>
@@ -114,28 +157,29 @@
<string name="are_you_interested">您仍感興趣嗎?</string>
<!-- General settings strings -->
- <string name="frame_limit_enable">啟用限制速度</string>
- <string name="frame_limit_enable_description">若啟用,模擬速度將會限制在標準速度的指定百分比。</string>
+ <string name="frame_limit_enable">限制速度</string>
+ <string name="frame_limit_enable_description">將模擬速度限制在標準速度的指定百分比。</string>
<string name="frame_limit_slider">限制速度百分比</string>
- <string name="frame_limit_slider_description">指定限制模擬速度的百分比。預設為 100%,模擬速度將被限制為標準速度。更高或更低的值將會增加或減少速度限制。</string>
+ <string name="frame_limit_slider_description">指定限制模擬速度的百分比。100% 為標準速度,更高或更低的值將會增加或減少速度限制。</string>
<string name="cpu_accuracy">CPU 準確度</string>
+ <string name="value_with_units">%1$s%2$s</string>
<!-- System settings strings -->
<string name="use_docked_mode">底座模式</string>
- <string name="use_docked_mode_description">以底座模式模擬,以犧牲效能的代價提高解析度。</string>
+ <string name="use_docked_mode_description">提高解析度,降低效能。停用後將會使用手提模式,會降低解析度並提高效能。</string>
<string name="emulated_region">模擬區域</string>
<string name="emulated_language">模擬語言</string>
<string name="select_rtc_date">選取 RTC 日期</string>
<string name="select_rtc_time">選取 RTC 時間</string>
- <string name="use_custom_rtc">啟用自訂 RTC</string>
- <string name="use_custom_rtc_description">此設定允許您設定與您的目前系統時間相互獨立的自訂即時時鐘</string>
+ <string name="use_custom_rtc">自訂 RTC</string>
+ <string name="use_custom_rtc_description">允許您設定與您的目前系統時間相互獨立的自訂即時時鐘。</string>
<string name="set_custom_rtc">設定自訂 RTC</string>
<!-- Graphics settings strings -->
- <string name="renderer_api">API</string>
<string name="renderer_accuracy">準確度層級</string>
- <string name="renderer_resolution">解析度</string>
+ <string name="renderer_resolution">解析度 (手提/底座)</string>
<string name="renderer_vsync">VSync 模式</string>
+ <string name="renderer_screen_layout">屏幕方向</string>
<string name="renderer_aspect_ratio">長寬比</string>
<string name="renderer_scaling_filter">視窗適應過濾器</string>
<string name="renderer_anti_aliasing">消除鋸齒方法</string>
@@ -143,12 +187,23 @@
<string name="renderer_force_max_clock_description">強制 GPU 以最大可能時脈執行 (熱溫限制仍被套用)。</string>
<string name="renderer_asynchronous_shaders">使用非同步著色器</string>
<string name="renderer_asynchronous_shaders_description">非同步編譯著色器,將會減少間斷,但可能會引入故障。</string>
- <string name="renderer_debug">啟用圖形偵錯</string>
- <string name="renderer_debug_description">核取時,圖形 API 將會進入慢速偵錯模式。</string>
- <string name="use_disk_shader_cache">使用磁碟著色器快取</string>
+ <string name="renderer_reactive_flushing">使用重新啟用排清</string>
+ <string name="renderer_reactive_flushing_description">犧牲效能,以改善部分遊戲的轉譯準確度。</string>
+ <string name="use_disk_shader_cache">磁碟著色器快取</string>
<string name="use_disk_shader_cache_description">透過將產生的著色器儲存並載入至磁碟,減少中斷。</string>
+ <!-- Debug settings strings -->
+ <string name="cpu">CPU</string>
+ <string name="cpu_debug_mode">CPU 调试</string>
+ <string name="cpu_debug_mode_description">将 CPU 设置为较慢的调试模式。</string>
+ <string name="gpu">GPU</string>
+ <string name="renderer_api">API</string>
+ <string name="renderer_debug">圖形偵錯</string>
+ <string name="renderer_debug_description">將圖形 API 設為慢速偵錯模式。</string>
+ <string name="fastmem">Fastmem</string>
+
<!-- Audio settings strings -->
+ <string name="audio_output_engine">输出引擎</string>
<string name="audio_volume">音量</string>
<string name="audio_volume_description">指定音訊輸出音量。</string>
@@ -157,7 +212,9 @@
<string name="ini_saved">已儲存設定</string>
<string name="gameid_saved">已儲存 %1$s 設定</string>
<string name="error_saving">儲存 %1$s 時發生錯誤 ini: %2$s</string>
+ <string name="unimplemented_menu">未生效菜单</string>
<string name="loading">正在載入…</string>
+ <string name="shutting_down">正在关闭…</string>
<string name="reset_setting_confirmation">要將此設定重設回預設值嗎?</string>
<string name="reset_to_default">重設為預設值</string>
<string name="reset_all_settings">重設所有設定?</string>
@@ -165,6 +222,14 @@
<string name="settings_reset">設定已重設</string>
<string name="close">關閉</string>
<string name="learn_more">深入瞭解</string>
+ <string name="auto">自動</string>
+ <string name="submit">提交</string>
+ <string name="string_null">無</string>
+ <string name="string_import">匯入</string>
+ <string name="export">匯出</string>
+ <string name="export_failed">导出失败</string>
+ <string name="import_failed">导入失败</string>
+ <string name="cancelling">取消中</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">選取 GPU 驅動程式</string>
@@ -172,6 +237,7 @@
<string name="select_gpu_driver_install">安裝</string>
<string name="select_gpu_driver_default">預設</string>
<string name="select_gpu_driver_use_default">使用預設 GPU 驅動程式</string>
+ <string name="select_gpu_driver_error">選取的驅動程式無效,將使用系統預設驅動程式!</string>
<string name="system_gpu_driver">系統 GPU 驅動程式</string>
<string name="installing_driver">正在安裝驅動程式…</string>
@@ -182,10 +248,11 @@
<string name="preferences_graphics">圖形</string>
<string name="preferences_audio">音訊</string>
<string name="preferences_theme">主題和色彩</string>
+ <string name="preferences_debug">偵錯</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">您的 ROM 已加密</string>
- <string name="loader_error_encrypted_roms_description"><![CDATA[請依循指南重新傾印您的<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">遊戲卡匣</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">安裝標題</a>。]]></string>
+ <string name="loader_error_encrypted_roms_description"><![CDATA[请按照指南重新转储您的<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">游戏卡带</a>或<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">已安装的游戏</a>。]]></string>
<string name="loader_error_encrypted_keys_description"><![CDATA[請確保您的 <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> 檔案已安裝,讓遊戲可以解密。]]></string>
<string name="loader_error_video_core">初始化視訊核心時發生錯誤</string>
<string name="loader_error_video_core_description">這經常由不相容的 GPU 驅動程式造成,安裝自訂 GPU 驅動程式可能會解決此問題。</string>
@@ -219,13 +286,16 @@
<!-- Errors and warnings -->
<string name="abort_button">中止</string>
<string name="continue_button">繼續</string>
- <string name="system_archive_not_found">找不到系統檔案</string>
+ <string name="system_archive_not_found">找不到系統封存</string>
<string name="system_archive_not_found_message">%s 遺失,請傾印您的系統封存。\n繼續模擬可能會造成當機和錯誤。</string>
<string name="system_archive_general">系統封存</string>
<string name="save_load_error">儲存/載入發生錯誤</string>
<string name="fatal_error">嚴重錯誤</string>
<string name="fatal_error_message">發生嚴重錯誤,檢查記錄以取得詳細資訊。\n繼續模擬可能會造成當機和錯誤。</string>
<string name="performance_warning">關閉此設定會顯著降低模擬效能!如需最佳體驗,建議您將此設定保持為啟用狀態。</string>
+ <string name="device_memory_inadequate">设备 RAM: %1$s\n推荐 RAM: %2$s</string>
+ <string name="memory_formatted">%1$s%2$s</string>
+ <string name="no_game_present">当前没有可启动的游戏!</string>
<!-- Region Names -->
<string name="region_japan">日本</string>
@@ -236,7 +306,14 @@
<string name="region_korea">南韓</string>
<string name="region_taiwan">台灣</string>
- <!-- Language Names -->
+ <!-- Memory Sizes -->
+ <string name="memory_byte">Byte</string>
+ <string name="memory_kilobyte">KB</string>
+ <string name="memory_megabyte">MB</string>
+ <string name="memory_gigabyte">英國</string>
+ <string name="memory_terabyte">TB</string>
+ <string name="memory_petabyte">PB</string>
+ <string name="memory_exabyte">EB</string>
<!-- Renderer APIs -->
<string name="renderer_vulkan">Vulkan</string>
@@ -274,14 +351,20 @@
<string name="anti_aliasing_fxaa">FXAA</string>
<string name="anti_aliasing_smaa">SMAA</string>
+ <!-- Screen Layouts -->
+ <string name="screen_layout_landscape">横向大屏</string>
+ <string name="screen_layout_portrait">纵向屏幕</string>
+ <string name="screen_layout_auto">自動</string>
+
<!-- Aspect Ratios -->
<string name="ratio_default">預設 (16:9)</string>
<string name="ratio_force_four_three">強制 4:3</string>
<string name="ratio_force_twenty_one_nine">強制 21:9</string>
<string name="ratio_force_sixteen_ten">強制 16:10</string>
- <string name="ratio_stretch">延伸視窗</string>
+ <string name="ratio_stretch">延展視窗</string>
<!-- CPU Accuracy -->
+ <string name="cpu_accuracy_accurate">高精度</string>
<string name="cpu_accuracy_unsafe">低精度</string>
<string name="cpu_accuracy_paranoid">不合理 (慢)</string>
@@ -307,8 +390,22 @@
<string name="theme_mode_light">淺色</string>
<string name="theme_mode_dark">深色</string>
+ <!-- Audio output engines -->
+ <string name="cubeb">cubeb</string>
+
<!-- Black backgrounds theme -->
- <string name="use_black_backgrounds">使用黑色背景</string>
+ <string name="use_black_backgrounds">黑色背景</string>
<string name="use_black_backgrounds_description">使用深色主題時,套用黑色背景。</string>
-</resources>
+ <!-- Picture-In-Picture -->
+ <string name="picture_in_picture">画中画</string>
+ <string name="picture_in_picture_description">模拟器位于后台时最小化窗口</string>
+ <string name="pause">暂停</string>
+ <string name="play">开始</string>
+ <string name="mute">靜音</string>
+ <string name="unmute">取消靜音</string>
+
+ <!-- Licenses screen strings -->
+ <string name="licenses">授權</string>
+ <string name="license_fidelityfx_fsr_description">來自 AMD 的升級圖像品質</string>
+ </resources>
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index dc10159c9..51bcc49a3 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -2,7 +2,6 @@
<resources>
<string-array name="regionNames">
- <item>@string/auto</item>
<item>@string/region_australia</item>
<item>@string/region_china</item>
<item>@string/region_europe</item>
@@ -13,7 +12,6 @@
</string-array>
<integer-array name="regionValues">
- <item>-1</item>
<item>3</item>
<item>4</item>
<item>2</item>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index b92978140..471af8795 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -72,7 +72,7 @@
<string name="invalid_keys_error">Invalid encryption keys</string>
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
<string name="install_keys_failure_description">The selected file is incorrect or corrupt. Please redump your keys.</string>
- <string name="gpu_driver_manager">GPU Driver Manager</string>
+ <string name="gpu_driver_manager">GPU driver manager</string>
<string name="install_gpu_driver">Install GPU driver</string>
<string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
<string name="advanced_settings">Advanced settings</string>
@@ -91,6 +91,7 @@
<string name="manage_save_data">Manage save data</string>
<string name="manage_save_data_description">Save data found. Please select an option below.</string>
<string name="import_export_saves_description">Import or export save files</string>
+ <string name="save_files_exporting">Exporting save files…</string>
<string name="save_file_imported_success">Imported successfully</string>
<string name="save_file_invalid_zip_structure">Invalid save directory structure</string>
<string name="save_file_invalid_zip_structure_description">The first subfolder name must be the title ID of the game.</string>
@@ -240,6 +241,7 @@
<string name="shutting_down">Shutting down…</string>
<string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string>
<string name="reset_to_default">Reset to default</string>
+ <string name="reset_to_default_description">Resets all advanced settings</string>
<string name="reset_all_settings">Reset all settings?</string>
<string name="reset_all_settings_description">All advanced settings will be reset to their default configuration. This can not be undone.</string>
<string name="settings_reset">Settings reset</string>
@@ -255,6 +257,7 @@
<string name="cancelling">Cancelling</string>
<string name="install">Install</string>
<string name="delete">Delete</string>
+ <string name="export_success">Exported successfully</string>
<!-- GPU driver installation -->
<string name="select_gpu_driver">Select GPU driver</string>
@@ -271,10 +274,14 @@
<string name="preferences_settings">Settings</string>
<string name="preferences_general">General</string>
<string name="preferences_system">System</string>
+ <string name="preferences_system_description">Docked mode, region, language</string>
<string name="preferences_graphics">Graphics</string>
+ <string name="preferences_graphics_description">Accuracy level, resolution, shader cache</string>
<string name="preferences_audio">Audio</string>
+ <string name="preferences_audio_description">Output engine, volume</string>
<string name="preferences_theme">Theme and color</string>
<string name="preferences_debug">Debug</string>
+ <string name="preferences_debug_description">CPU/GPU debugging, graphics API, fastmem</string>
<!-- ROM loading errors -->
<string name="loader_error_encrypted">Your ROM is encrypted</string>
diff --git a/src/android/app/src/main/res/xml/locales_config.xml b/src/android/app/src/main/res/xml/locales_config.xml
deleted file mode 100644
index 51b88d9dc..000000000
--- a/src/android/app/src/main/res/xml/locales_config.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
- <locale android:name="en" /> <!-- English (default) -->
- <locale android:name="de" /> <!-- German -->
- <locale android:name="es" /> <!-- Spanish -->
- <locale android:name="fr" /> <!-- French -->
- <locale android:name="it" /> <!-- Italian -->
- <locale android:name="ja" /> <!-- Japanese -->
- <locale android:name="nb" /> <!-- Norwegian Bokmal -->
- <locale android:name="pl" /> <!-- Polish -->
- <locale android:name="pt-rBR" /> <!-- Portuguese (Brazil) -->
- <locale android:name="pt-RPT" /> <!-- Portuguese (Portugal) -->
- <locale android:name="ru" /> <!-- Russian -->
- <locale android:name="uk" /> <!-- Ukranian -->
- <locale android:name="zh-rCN" /> <!-- Chinese (China) -->
- <locale android:name="zh-rTW" /> <!-- Chinese (Taiwan) -->
-</locale-config>
diff --git a/src/audio_core/adsp/apps/opus/opus_decode_object.cpp b/src/audio_core/adsp/apps/opus/opus_decode_object.cpp
index 2c16d3769..e2b9eb566 100644
--- a/src/audio_core/adsp/apps/opus/opus_decode_object.cpp
+++ b/src/audio_core/adsp/apps/opus/opus_decode_object.cpp
@@ -1,107 +1,107 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "audio_core/adsp/apps/opus/opus_decode_object.h"
-#include "common/assert.h"
-
-namespace AudioCore::ADSP::OpusDecoder {
-namespace {
-bool IsValidChannelCount(u32 channel_count) {
- return channel_count == 1 || channel_count == 2;
-}
-} // namespace
-
-u32 OpusDecodeObject::GetWorkBufferSize(u32 channel_count) {
- if (!IsValidChannelCount(channel_count)) {
- return 0;
- }
- return static_cast<u32>(sizeof(OpusDecodeObject)) + opus_decoder_get_size(channel_count);
-}
-
-OpusDecodeObject& OpusDecodeObject::Initialize(u64 buffer, u64 buffer2) {
- auto* new_decoder = reinterpret_cast<OpusDecodeObject*>(buffer);
- auto* comparison = reinterpret_cast<OpusDecodeObject*>(buffer2);
-
- if (new_decoder->magic == DecodeObjectMagic) {
- if (!new_decoder->initialized ||
- (new_decoder->initialized && new_decoder->self == comparison)) {
- new_decoder->state_valid = true;
- }
- } else {
- new_decoder->initialized = false;
- new_decoder->state_valid = true;
- }
- return *new_decoder;
-}
-
-s32 OpusDecodeObject::InitializeDecoder(u32 sample_rate, u32 channel_count) {
- if (!state_valid) {
- return OPUS_INVALID_STATE;
- }
-
- if (initialized) {
- return OPUS_OK;
- }
-
- // Unfortunately libopus does not expose the OpusDecoder struct publicly, so we can't include
- // it in this class. Nintendo does not allocate memory, which is why we have a workbuffer
- // provided.
- // We could use _create and have libopus allocate it for us, but then we have to separately
- // track which decoder is being used between this and multistream in order to call the correct
- // destroy from the host side.
- // This is a bit cringe, but is safe as these objects are only ever initialized inside the given
- // workbuffer, and GetWorkBufferSize will guarantee there's enough space to follow.
- decoder = (LibOpusDecoder*)(this + 1);
- s32 ret = opus_decoder_init(decoder, sample_rate, channel_count);
- if (ret == OPUS_OK) {
- magic = DecodeObjectMagic;
- initialized = true;
- state_valid = true;
- self = this;
- final_range = 0;
- }
- return ret;
-}
-
-s32 OpusDecodeObject::Shutdown() {
- if (!state_valid) {
- return OPUS_INVALID_STATE;
- }
-
- if (initialized) {
- magic = 0x0;
- initialized = false;
- state_valid = false;
- self = nullptr;
- final_range = 0;
- decoder = nullptr;
- }
- return OPUS_OK;
-}
-
-s32 OpusDecodeObject::ResetDecoder() {
- return opus_decoder_ctl(decoder, OPUS_RESET_STATE);
-}
-
-s32 OpusDecodeObject::Decode(u32& out_sample_count, u64 output_data, u64 output_data_size,
- u64 input_data, u64 input_data_size) {
- ASSERT(initialized);
- out_sample_count = 0;
-
- if (!state_valid) {
- return OPUS_INVALID_STATE;
- }
-
- auto ret_code_or_samples = opus_decode(
- decoder, reinterpret_cast<const u8*>(input_data), static_cast<opus_int32>(input_data_size),
- reinterpret_cast<opus_int16*>(output_data), static_cast<opus_int32>(output_data_size), 0);
-
- if (ret_code_or_samples < OPUS_OK) {
- return ret_code_or_samples;
- }
-
- out_sample_count = ret_code_or_samples;
- return opus_decoder_ctl(decoder, OPUS_GET_FINAL_RANGE_REQUEST, &final_range);
-}
-
-} // namespace AudioCore::ADSP::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/adsp/apps/opus/opus_decode_object.h"
+#include "common/assert.h"
+
+namespace AudioCore::ADSP::OpusDecoder {
+namespace {
+bool IsValidChannelCount(u32 channel_count) {
+ return channel_count == 1 || channel_count == 2;
+}
+} // namespace
+
+u32 OpusDecodeObject::GetWorkBufferSize(u32 channel_count) {
+ if (!IsValidChannelCount(channel_count)) {
+ return 0;
+ }
+ return static_cast<u32>(sizeof(OpusDecodeObject)) + opus_decoder_get_size(channel_count);
+}
+
+OpusDecodeObject& OpusDecodeObject::Initialize(u64 buffer, u64 buffer2) {
+ auto* new_decoder = reinterpret_cast<OpusDecodeObject*>(buffer);
+ auto* comparison = reinterpret_cast<OpusDecodeObject*>(buffer2);
+
+ if (new_decoder->magic == DecodeObjectMagic) {
+ if (!new_decoder->initialized ||
+ (new_decoder->initialized && new_decoder->self == comparison)) {
+ new_decoder->state_valid = true;
+ }
+ } else {
+ new_decoder->initialized = false;
+ new_decoder->state_valid = true;
+ }
+ return *new_decoder;
+}
+
+s32 OpusDecodeObject::InitializeDecoder(u32 sample_rate, u32 channel_count) {
+ if (!state_valid) {
+ return OPUS_INVALID_STATE;
+ }
+
+ if (initialized) {
+ return OPUS_OK;
+ }
+
+ // Unfortunately libopus does not expose the OpusDecoder struct publicly, so we can't include
+ // it in this class. Nintendo does not allocate memory, which is why we have a workbuffer
+ // provided.
+ // We could use _create and have libopus allocate it for us, but then we have to separately
+ // track which decoder is being used between this and multistream in order to call the correct
+ // destroy from the host side.
+ // This is a bit cringe, but is safe as these objects are only ever initialized inside the given
+ // workbuffer, and GetWorkBufferSize will guarantee there's enough space to follow.
+ decoder = (LibOpusDecoder*)(this + 1);
+ s32 ret = opus_decoder_init(decoder, sample_rate, channel_count);
+ if (ret == OPUS_OK) {
+ magic = DecodeObjectMagic;
+ initialized = true;
+ state_valid = true;
+ self = this;
+ final_range = 0;
+ }
+ return ret;
+}
+
+s32 OpusDecodeObject::Shutdown() {
+ if (!state_valid) {
+ return OPUS_INVALID_STATE;
+ }
+
+ if (initialized) {
+ magic = 0x0;
+ initialized = false;
+ state_valid = false;
+ self = nullptr;
+ final_range = 0;
+ decoder = nullptr;
+ }
+ return OPUS_OK;
+}
+
+s32 OpusDecodeObject::ResetDecoder() {
+ return opus_decoder_ctl(decoder, OPUS_RESET_STATE);
+}
+
+s32 OpusDecodeObject::Decode(u32& out_sample_count, u64 output_data, u64 output_data_size,
+ u64 input_data, u64 input_data_size) {
+ ASSERT(initialized);
+ out_sample_count = 0;
+
+ if (!state_valid) {
+ return OPUS_INVALID_STATE;
+ }
+
+ auto ret_code_or_samples = opus_decode(
+ decoder, reinterpret_cast<const u8*>(input_data), static_cast<opus_int32>(input_data_size),
+ reinterpret_cast<opus_int16*>(output_data), static_cast<opus_int32>(output_data_size), 0);
+
+ if (ret_code_or_samples < OPUS_OK) {
+ return ret_code_or_samples;
+ }
+
+ out_sample_count = ret_code_or_samples;
+ return opus_decoder_ctl(decoder, OPUS_GET_FINAL_RANGE_REQUEST, &final_range);
+}
+
+} // namespace AudioCore::ADSP::OpusDecoder
diff --git a/src/audio_core/adsp/apps/opus/opus_decoder.cpp b/src/audio_core/adsp/apps/opus/opus_decoder.cpp
index 2084de128..75f0fb9ad 100644
--- a/src/audio_core/adsp/apps/opus/opus_decoder.cpp
+++ b/src/audio_core/adsp/apps/opus/opus_decoder.cpp
@@ -30,9 +30,9 @@ bool IsValidMultiStreamChannelCount(u32 channel_count) {
return channel_count <= OpusStreamCountMax;
}
-bool IsValidMultiStreamStreamCounts(s32 total_stream_count, s32 sterero_stream_count) {
+bool IsValidMultiStreamStreamCounts(s32 total_stream_count, s32 stereo_stream_count) {
return IsValidMultiStreamChannelCount(total_stream_count) && total_stream_count > 0 &&
- sterero_stream_count > 0 && sterero_stream_count <= total_stream_count;
+ stereo_stream_count >= 0 && stereo_stream_count <= total_stream_count;
}
} // namespace
diff --git a/src/audio_core/adsp/apps/opus/opus_multistream_decode_object.cpp b/src/audio_core/adsp/apps/opus/opus_multistream_decode_object.cpp
index f6d362e68..05cf3975d 100644
--- a/src/audio_core/adsp/apps/opus/opus_multistream_decode_object.cpp
+++ b/src/audio_core/adsp/apps/opus/opus_multistream_decode_object.cpp
@@ -1,111 +1,111 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "audio_core/adsp/apps/opus/opus_multistream_decode_object.h"
-#include "common/assert.h"
-
-namespace AudioCore::ADSP::OpusDecoder {
-
-namespace {
-bool IsValidChannelCount(u32 channel_count) {
- return channel_count == 1 || channel_count == 2;
-}
-
-bool IsValidStreamCounts(u32 total_stream_count, u32 stereo_stream_count) {
- return total_stream_count > 0 && stereo_stream_count > 0 &&
- stereo_stream_count <= total_stream_count && IsValidChannelCount(total_stream_count);
-}
-} // namespace
-
-u32 OpusMultiStreamDecodeObject::GetWorkBufferSize(u32 total_stream_count,
- u32 stereo_stream_count) {
- if (IsValidStreamCounts(total_stream_count, stereo_stream_count)) {
- return static_cast<u32>(sizeof(OpusMultiStreamDecodeObject)) +
- opus_multistream_decoder_get_size(total_stream_count, stereo_stream_count);
- }
- return 0;
-}
-
-OpusMultiStreamDecodeObject& OpusMultiStreamDecodeObject::Initialize(u64 buffer, u64 buffer2) {
- auto* new_decoder = reinterpret_cast<OpusMultiStreamDecodeObject*>(buffer);
- auto* comparison = reinterpret_cast<OpusMultiStreamDecodeObject*>(buffer2);
-
- if (new_decoder->magic == DecodeMultiStreamObjectMagic) {
- if (!new_decoder->initialized ||
- (new_decoder->initialized && new_decoder->self == comparison)) {
- new_decoder->state_valid = true;
- }
- } else {
- new_decoder->initialized = false;
- new_decoder->state_valid = true;
- }
- return *new_decoder;
-}
-
-s32 OpusMultiStreamDecodeObject::InitializeDecoder(u32 sample_rate, u32 total_stream_count,
- u32 channel_count, u32 stereo_stream_count,
- u8* mappings) {
- if (!state_valid) {
- return OPUS_INVALID_STATE;
- }
-
- if (initialized) {
- return OPUS_OK;
- }
-
- // See OpusDecodeObject::InitializeDecoder for an explanation of this
- decoder = (LibOpusMSDecoder*)(this + 1);
- s32 ret = opus_multistream_decoder_init(decoder, sample_rate, channel_count, total_stream_count,
- stereo_stream_count, mappings);
- if (ret == OPUS_OK) {
- magic = DecodeMultiStreamObjectMagic;
- initialized = true;
- state_valid = true;
- self = this;
- final_range = 0;
- }
- return ret;
-}
-
-s32 OpusMultiStreamDecodeObject::Shutdown() {
- if (!state_valid) {
- return OPUS_INVALID_STATE;
- }
-
- if (initialized) {
- magic = 0x0;
- initialized = false;
- state_valid = false;
- self = nullptr;
- final_range = 0;
- decoder = nullptr;
- }
- return OPUS_OK;
-}
-
-s32 OpusMultiStreamDecodeObject::ResetDecoder() {
- return opus_multistream_decoder_ctl(decoder, OPUS_RESET_STATE);
-}
-
-s32 OpusMultiStreamDecodeObject::Decode(u32& out_sample_count, u64 output_data,
- u64 output_data_size, u64 input_data, u64 input_data_size) {
- ASSERT(initialized);
- out_sample_count = 0;
-
- if (!state_valid) {
- return OPUS_INVALID_STATE;
- }
-
- auto ret_code_or_samples = opus_multistream_decode(
- decoder, reinterpret_cast<const u8*>(input_data), static_cast<opus_int32>(input_data_size),
- reinterpret_cast<opus_int16*>(output_data), static_cast<opus_int32>(output_data_size), 0);
-
- if (ret_code_or_samples < OPUS_OK) {
- return ret_code_or_samples;
- }
-
- out_sample_count = ret_code_or_samples;
- return opus_multistream_decoder_ctl(decoder, OPUS_GET_FINAL_RANGE_REQUEST, &final_range);
-}
-
-} // namespace AudioCore::ADSP::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/adsp/apps/opus/opus_multistream_decode_object.h"
+#include "common/assert.h"
+
+namespace AudioCore::ADSP::OpusDecoder {
+
+namespace {
+bool IsValidChannelCount(u32 channel_count) {
+ return channel_count == 1 || channel_count == 2;
+}
+
+bool IsValidStreamCounts(u32 total_stream_count, u32 stereo_stream_count) {
+ return total_stream_count > 0 && static_cast<s32>(stereo_stream_count) >= 0 &&
+ stereo_stream_count <= total_stream_count && IsValidChannelCount(total_stream_count);
+}
+} // namespace
+
+u32 OpusMultiStreamDecodeObject::GetWorkBufferSize(u32 total_stream_count,
+ u32 stereo_stream_count) {
+ if (IsValidStreamCounts(total_stream_count, stereo_stream_count)) {
+ return static_cast<u32>(sizeof(OpusMultiStreamDecodeObject)) +
+ opus_multistream_decoder_get_size(total_stream_count, stereo_stream_count);
+ }
+ return 0;
+}
+
+OpusMultiStreamDecodeObject& OpusMultiStreamDecodeObject::Initialize(u64 buffer, u64 buffer2) {
+ auto* new_decoder = reinterpret_cast<OpusMultiStreamDecodeObject*>(buffer);
+ auto* comparison = reinterpret_cast<OpusMultiStreamDecodeObject*>(buffer2);
+
+ if (new_decoder->magic == DecodeMultiStreamObjectMagic) {
+ if (!new_decoder->initialized ||
+ (new_decoder->initialized && new_decoder->self == comparison)) {
+ new_decoder->state_valid = true;
+ }
+ } else {
+ new_decoder->initialized = false;
+ new_decoder->state_valid = true;
+ }
+ return *new_decoder;
+}
+
+s32 OpusMultiStreamDecodeObject::InitializeDecoder(u32 sample_rate, u32 total_stream_count,
+ u32 channel_count, u32 stereo_stream_count,
+ u8* mappings) {
+ if (!state_valid) {
+ return OPUS_INVALID_STATE;
+ }
+
+ if (initialized) {
+ return OPUS_OK;
+ }
+
+ // See OpusDecodeObject::InitializeDecoder for an explanation of this
+ decoder = (LibOpusMSDecoder*)(this + 1);
+ s32 ret = opus_multistream_decoder_init(decoder, sample_rate, channel_count, total_stream_count,
+ stereo_stream_count, mappings);
+ if (ret == OPUS_OK) {
+ magic = DecodeMultiStreamObjectMagic;
+ initialized = true;
+ state_valid = true;
+ self = this;
+ final_range = 0;
+ }
+ return ret;
+}
+
+s32 OpusMultiStreamDecodeObject::Shutdown() {
+ if (!state_valid) {
+ return OPUS_INVALID_STATE;
+ }
+
+ if (initialized) {
+ magic = 0x0;
+ initialized = false;
+ state_valid = false;
+ self = nullptr;
+ final_range = 0;
+ decoder = nullptr;
+ }
+ return OPUS_OK;
+}
+
+s32 OpusMultiStreamDecodeObject::ResetDecoder() {
+ return opus_multistream_decoder_ctl(decoder, OPUS_RESET_STATE);
+}
+
+s32 OpusMultiStreamDecodeObject::Decode(u32& out_sample_count, u64 output_data,
+ u64 output_data_size, u64 input_data, u64 input_data_size) {
+ ASSERT(initialized);
+ out_sample_count = 0;
+
+ if (!state_valid) {
+ return OPUS_INVALID_STATE;
+ }
+
+ auto ret_code_or_samples = opus_multistream_decode(
+ decoder, reinterpret_cast<const u8*>(input_data), static_cast<opus_int32>(input_data_size),
+ reinterpret_cast<opus_int16*>(output_data), static_cast<opus_int32>(output_data_size), 0);
+
+ if (ret_code_or_samples < OPUS_OK) {
+ return ret_code_or_samples;
+ }
+
+ out_sample_count = ret_code_or_samples;
+ return opus_multistream_decoder_ctl(decoder, OPUS_GET_FINAL_RANGE_REQUEST, &final_range);
+}
+
+} // namespace AudioCore::ADSP::OpusDecoder
diff --git a/src/audio_core/opus/decoder.cpp b/src/audio_core/opus/decoder.cpp
index 5b23fce14..b7fed5304 100644
--- a/src/audio_core/opus/decoder.cpp
+++ b/src/audio_core/opus/decoder.cpp
@@ -1,179 +1,179 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "audio_core/opus/decoder.h"
-#include "audio_core/opus/hardware_opus.h"
-#include "audio_core/opus/parameters.h"
-#include "common/alignment.h"
-#include "common/swap.h"
-#include "core/core.h"
-
-namespace AudioCore::OpusDecoder {
-using namespace Service::Audio;
-namespace {
-OpusPacketHeader ReverseHeader(OpusPacketHeader header) {
- OpusPacketHeader out;
- out.size = Common::swap32(header.size);
- out.final_range = Common::swap32(header.final_range);
- return out;
-}
-} // namespace
-
-OpusDecoder::OpusDecoder(Core::System& system_, HardwareOpus& hardware_opus_)
- : system{system_}, hardware_opus{hardware_opus_} {}
-
-OpusDecoder::~OpusDecoder() {
- if (decode_object_initialized) {
- hardware_opus.ShutdownDecodeObject(shared_buffer.get(), shared_buffer_size);
- }
-}
-
-Result OpusDecoder::Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory,
- u64 transfer_memory_size) {
- auto frame_size{params.use_large_frame_size ? 5760 : 1920};
- shared_buffer_size = transfer_memory_size;
- shared_buffer = std::make_unique<u8[]>(shared_buffer_size);
- shared_memory_mapped = true;
-
- buffer_size =
- Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 16);
-
- out_data = {shared_buffer.get() + shared_buffer_size - buffer_size, buffer_size};
- size_t in_data_size{0x600u};
- in_data = {out_data.data() - in_data_size, in_data_size};
-
- ON_RESULT_FAILURE {
- if (shared_memory_mapped) {
- shared_memory_mapped = false;
- ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.get(), shared_buffer_size)));
- }
- };
-
- R_TRY(hardware_opus.InitializeDecodeObject(params.sample_rate, params.channel_count,
- shared_buffer.get(), shared_buffer_size));
-
- sample_rate = params.sample_rate;
- channel_count = params.channel_count;
- use_large_frame_size = params.use_large_frame_size;
- decode_object_initialized = true;
- R_SUCCEED();
-}
-
-Result OpusDecoder::Initialize(OpusMultiStreamParametersEx& params,
- Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
- auto frame_size{params.use_large_frame_size ? 5760 : 1920};
- shared_buffer_size = transfer_memory_size;
- shared_buffer = std::make_unique<u8[]>(shared_buffer_size);
- shared_memory_mapped = true;
-
- buffer_size =
- Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 16);
-
- out_data = {shared_buffer.get() + shared_buffer_size - buffer_size, buffer_size};
- size_t in_data_size{Common::AlignUp(1500ull * params.total_stream_count, 64u)};
- in_data = {out_data.data() - in_data_size, in_data_size};
-
- ON_RESULT_FAILURE {
- if (shared_memory_mapped) {
- shared_memory_mapped = false;
- ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.get(), shared_buffer_size)));
- }
- };
-
- R_TRY(hardware_opus.InitializeMultiStreamDecodeObject(
- params.sample_rate, params.channel_count, params.total_stream_count,
- params.stereo_stream_count, params.mappings.data(), shared_buffer.get(),
- shared_buffer_size));
-
- sample_rate = params.sample_rate;
- channel_count = params.channel_count;
- total_stream_count = params.total_stream_count;
- stereo_stream_count = params.stereo_stream_count;
- use_large_frame_size = params.use_large_frame_size;
- decode_object_initialized = true;
- R_SUCCEED();
-}
-
-Result OpusDecoder::DecodeInterleaved(u32* out_data_size, u64* out_time_taken,
- u32* out_sample_count, std::span<const u8> input_data,
- std::span<u8> output_data, bool reset) {
- u32 out_samples;
- u64 time_taken{};
-
- R_UNLESS(input_data.size_bytes() > sizeof(OpusPacketHeader), ResultInputDataTooSmall);
-
- auto* header_p{reinterpret_cast<const OpusPacketHeader*>(input_data.data())};
- OpusPacketHeader header{ReverseHeader(*header_p)};
-
- R_UNLESS(in_data.size_bytes() >= header.size &&
- header.size + sizeof(OpusPacketHeader) <= input_data.size_bytes(),
- ResultBufferTooSmall);
-
- if (!shared_memory_mapped) {
- R_TRY(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
- shared_memory_mapped = true;
- }
-
- std::memcpy(in_data.data(), input_data.data() + sizeof(OpusPacketHeader), header.size);
-
- R_TRY(hardware_opus.DecodeInterleaved(out_samples, out_data.data(), out_data.size_bytes(),
- channel_count, in_data.data(), header.size,
- shared_buffer.get(), time_taken, reset));
-
- std::memcpy(output_data.data(), out_data.data(), out_samples * channel_count * sizeof(s16));
-
- *out_data_size = header.size + sizeof(OpusPacketHeader);
- *out_sample_count = out_samples;
- if (out_time_taken) {
- *out_time_taken = time_taken / 1000;
- }
- R_SUCCEED();
-}
-
-Result OpusDecoder::SetContext([[maybe_unused]] std::span<const u8> context) {
- R_SUCCEED_IF(shared_memory_mapped);
- shared_memory_mapped = true;
- R_RETURN(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
-}
-
-Result OpusDecoder::DecodeInterleavedForMultiStream(u32* out_data_size, u64* out_time_taken,
- u32* out_sample_count,
- std::span<const u8> input_data,
- std::span<u8> output_data, bool reset) {
- u32 out_samples;
- u64 time_taken{};
-
- R_UNLESS(input_data.size_bytes() > sizeof(OpusPacketHeader), ResultInputDataTooSmall);
-
- auto* header_p{reinterpret_cast<const OpusPacketHeader*>(input_data.data())};
- OpusPacketHeader header{ReverseHeader(*header_p)};
-
- LOG_ERROR(Service_Audio, "header size 0x{:X} input data size 0x{:X} in_data size 0x{:X}",
- header.size, input_data.size_bytes(), in_data.size_bytes());
-
- R_UNLESS(in_data.size_bytes() >= header.size &&
- header.size + sizeof(OpusPacketHeader) <= input_data.size_bytes(),
- ResultBufferTooSmall);
-
- if (!shared_memory_mapped) {
- R_TRY(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
- shared_memory_mapped = true;
- }
-
- std::memcpy(in_data.data(), input_data.data() + sizeof(OpusPacketHeader), header.size);
-
- R_TRY(hardware_opus.DecodeInterleavedForMultiStream(
- out_samples, out_data.data(), out_data.size_bytes(), channel_count, in_data.data(),
- header.size, shared_buffer.get(), time_taken, reset));
-
- std::memcpy(output_data.data(), out_data.data(), out_samples * channel_count * sizeof(s16));
-
- *out_data_size = header.size + sizeof(OpusPacketHeader);
- *out_sample_count = out_samples;
- if (out_time_taken) {
- *out_time_taken = time_taken / 1000;
- }
- R_SUCCEED();
-}
-
-} // namespace AudioCore::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/opus/decoder.h"
+#include "audio_core/opus/hardware_opus.h"
+#include "audio_core/opus/parameters.h"
+#include "common/alignment.h"
+#include "common/swap.h"
+#include "core/core.h"
+
+namespace AudioCore::OpusDecoder {
+using namespace Service::Audio;
+namespace {
+OpusPacketHeader ReverseHeader(OpusPacketHeader header) {
+ OpusPacketHeader out;
+ out.size = Common::swap32(header.size);
+ out.final_range = Common::swap32(header.final_range);
+ return out;
+}
+} // namespace
+
+OpusDecoder::OpusDecoder(Core::System& system_, HardwareOpus& hardware_opus_)
+ : system{system_}, hardware_opus{hardware_opus_} {}
+
+OpusDecoder::~OpusDecoder() {
+ if (decode_object_initialized) {
+ hardware_opus.ShutdownDecodeObject(shared_buffer.get(), shared_buffer_size);
+ }
+}
+
+Result OpusDecoder::Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory,
+ u64 transfer_memory_size) {
+ auto frame_size{params.use_large_frame_size ? 5760 : 1920};
+ shared_buffer_size = transfer_memory_size;
+ shared_buffer = std::make_unique<u8[]>(shared_buffer_size);
+ shared_memory_mapped = true;
+
+ buffer_size =
+ Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 16);
+
+ out_data = {shared_buffer.get() + shared_buffer_size - buffer_size, buffer_size};
+ size_t in_data_size{0x600u};
+ in_data = {out_data.data() - in_data_size, in_data_size};
+
+ ON_RESULT_FAILURE {
+ if (shared_memory_mapped) {
+ shared_memory_mapped = false;
+ ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.get(), shared_buffer_size)));
+ }
+ };
+
+ R_TRY(hardware_opus.InitializeDecodeObject(params.sample_rate, params.channel_count,
+ shared_buffer.get(), shared_buffer_size));
+
+ sample_rate = params.sample_rate;
+ channel_count = params.channel_count;
+ use_large_frame_size = params.use_large_frame_size;
+ decode_object_initialized = true;
+ R_SUCCEED();
+}
+
+Result OpusDecoder::Initialize(OpusMultiStreamParametersEx& params,
+ Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
+ auto frame_size{params.use_large_frame_size ? 5760 : 1920};
+ shared_buffer_size = transfer_memory_size;
+ shared_buffer = std::make_unique<u8[]>(shared_buffer_size);
+ shared_memory_mapped = true;
+
+ buffer_size =
+ Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 16);
+
+ out_data = {shared_buffer.get() + shared_buffer_size - buffer_size, buffer_size};
+ size_t in_data_size{Common::AlignUp(1500ull * params.total_stream_count, 64u)};
+ in_data = {out_data.data() - in_data_size, in_data_size};
+
+ ON_RESULT_FAILURE {
+ if (shared_memory_mapped) {
+ shared_memory_mapped = false;
+ ASSERT(R_SUCCEEDED(hardware_opus.UnmapMemory(shared_buffer.get(), shared_buffer_size)));
+ }
+ };
+
+ R_TRY(hardware_opus.InitializeMultiStreamDecodeObject(
+ params.sample_rate, params.channel_count, params.total_stream_count,
+ params.stereo_stream_count, params.mappings.data(), shared_buffer.get(),
+ shared_buffer_size));
+
+ sample_rate = params.sample_rate;
+ channel_count = params.channel_count;
+ total_stream_count = params.total_stream_count;
+ stereo_stream_count = params.stereo_stream_count;
+ use_large_frame_size = params.use_large_frame_size;
+ decode_object_initialized = true;
+ R_SUCCEED();
+}
+
+Result OpusDecoder::DecodeInterleaved(u32* out_data_size, u64* out_time_taken,
+ u32* out_sample_count, std::span<const u8> input_data,
+ std::span<u8> output_data, bool reset) {
+ u32 out_samples;
+ u64 time_taken{};
+
+ R_UNLESS(input_data.size_bytes() > sizeof(OpusPacketHeader), ResultInputDataTooSmall);
+
+ auto* header_p{reinterpret_cast<const OpusPacketHeader*>(input_data.data())};
+ OpusPacketHeader header{ReverseHeader(*header_p)};
+
+ R_UNLESS(in_data.size_bytes() >= header.size &&
+ header.size + sizeof(OpusPacketHeader) <= input_data.size_bytes(),
+ ResultBufferTooSmall);
+
+ if (!shared_memory_mapped) {
+ R_TRY(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
+ shared_memory_mapped = true;
+ }
+
+ std::memcpy(in_data.data(), input_data.data() + sizeof(OpusPacketHeader), header.size);
+
+ R_TRY(hardware_opus.DecodeInterleaved(out_samples, out_data.data(), out_data.size_bytes(),
+ channel_count, in_data.data(), header.size,
+ shared_buffer.get(), time_taken, reset));
+
+ std::memcpy(output_data.data(), out_data.data(), out_samples * channel_count * sizeof(s16));
+
+ *out_data_size = header.size + sizeof(OpusPacketHeader);
+ *out_sample_count = out_samples;
+ if (out_time_taken) {
+ *out_time_taken = time_taken / 1000;
+ }
+ R_SUCCEED();
+}
+
+Result OpusDecoder::SetContext([[maybe_unused]] std::span<const u8> context) {
+ R_SUCCEED_IF(shared_memory_mapped);
+ shared_memory_mapped = true;
+ R_RETURN(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
+}
+
+Result OpusDecoder::DecodeInterleavedForMultiStream(u32* out_data_size, u64* out_time_taken,
+ u32* out_sample_count,
+ std::span<const u8> input_data,
+ std::span<u8> output_data, bool reset) {
+ u32 out_samples;
+ u64 time_taken{};
+
+ R_UNLESS(input_data.size_bytes() > sizeof(OpusPacketHeader), ResultInputDataTooSmall);
+
+ auto* header_p{reinterpret_cast<const OpusPacketHeader*>(input_data.data())};
+ OpusPacketHeader header{ReverseHeader(*header_p)};
+
+ LOG_TRACE(Service_Audio, "header size 0x{:X} input data size 0x{:X} in_data size 0x{:X}",
+ header.size, input_data.size_bytes(), in_data.size_bytes());
+
+ R_UNLESS(in_data.size_bytes() >= header.size &&
+ header.size + sizeof(OpusPacketHeader) <= input_data.size_bytes(),
+ ResultBufferTooSmall);
+
+ if (!shared_memory_mapped) {
+ R_TRY(hardware_opus.MapMemory(shared_buffer.get(), shared_buffer_size));
+ shared_memory_mapped = true;
+ }
+
+ std::memcpy(in_data.data(), input_data.data() + sizeof(OpusPacketHeader), header.size);
+
+ R_TRY(hardware_opus.DecodeInterleavedForMultiStream(
+ out_samples, out_data.data(), out_data.size_bytes(), channel_count, in_data.data(),
+ header.size, shared_buffer.get(), time_taken, reset));
+
+ std::memcpy(output_data.data(), out_data.data(), out_samples * channel_count * sizeof(s16));
+
+ *out_data_size = header.size + sizeof(OpusPacketHeader);
+ *out_sample_count = out_samples;
+ if (out_time_taken) {
+ *out_time_taken = time_taken / 1000;
+ }
+ R_SUCCEED();
+}
+
+} // namespace AudioCore::OpusDecoder
diff --git a/src/audio_core/opus/decoder.h b/src/audio_core/opus/decoder.h
index d08d8a4a4..fd728958a 100644
--- a/src/audio_core/opus/decoder.h
+++ b/src/audio_core/opus/decoder.h
@@ -1,53 +1,53 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <span>
-
-#include "audio_core/opus/parameters.h"
-#include "common/common_types.h"
-#include "core/hle/kernel/k_transfer_memory.h"
-#include "core/hle/service/audio/errors.h"
-
-namespace Core {
-class System;
-}
-
-namespace AudioCore::OpusDecoder {
-class HardwareOpus;
-
-class OpusDecoder {
-public:
- explicit OpusDecoder(Core::System& system, HardwareOpus& hardware_opus_);
- ~OpusDecoder();
-
- Result Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory,
- u64 transfer_memory_size);
- Result Initialize(OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory,
- u64 transfer_memory_size);
- Result DecodeInterleaved(u32* out_data_size, u64* out_time_taken, u32* out_sample_count,
- std::span<const u8> input_data, std::span<u8> output_data, bool reset);
- Result SetContext([[maybe_unused]] std::span<const u8> context);
- Result DecodeInterleavedForMultiStream(u32* out_data_size, u64* out_time_taken,
- u32* out_sample_count, std::span<const u8> input_data,
- std::span<u8> output_data, bool reset);
-
-private:
- Core::System& system;
- HardwareOpus& hardware_opus;
- std::unique_ptr<u8[]> shared_buffer{};
- u64 shared_buffer_size;
- std::span<u8> in_data{};
- std::span<u8> out_data{};
- u64 buffer_size{};
- s32 sample_rate{};
- s32 channel_count{};
- bool use_large_frame_size{false};
- s32 total_stream_count{};
- s32 stereo_stream_count{};
- bool shared_memory_mapped{false};
- bool decode_object_initialized{false};
-};
-
-} // namespace AudioCore::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <span>
+
+#include "audio_core/opus/parameters.h"
+#include "common/common_types.h"
+#include "core/hle/kernel/k_transfer_memory.h"
+#include "core/hle/service/audio/errors.h"
+
+namespace Core {
+class System;
+}
+
+namespace AudioCore::OpusDecoder {
+class HardwareOpus;
+
+class OpusDecoder {
+public:
+ explicit OpusDecoder(Core::System& system, HardwareOpus& hardware_opus_);
+ ~OpusDecoder();
+
+ Result Initialize(OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory,
+ u64 transfer_memory_size);
+ Result Initialize(OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory,
+ u64 transfer_memory_size);
+ Result DecodeInterleaved(u32* out_data_size, u64* out_time_taken, u32* out_sample_count,
+ std::span<const u8> input_data, std::span<u8> output_data, bool reset);
+ Result SetContext([[maybe_unused]] std::span<const u8> context);
+ Result DecodeInterleavedForMultiStream(u32* out_data_size, u64* out_time_taken,
+ u32* out_sample_count, std::span<const u8> input_data,
+ std::span<u8> output_data, bool reset);
+
+private:
+ Core::System& system;
+ HardwareOpus& hardware_opus;
+ std::unique_ptr<u8[]> shared_buffer{};
+ u64 shared_buffer_size;
+ std::span<u8> in_data{};
+ std::span<u8> out_data{};
+ u64 buffer_size{};
+ s32 sample_rate{};
+ s32 channel_count{};
+ bool use_large_frame_size{false};
+ s32 total_stream_count{};
+ s32 stereo_stream_count{};
+ bool shared_memory_mapped{false};
+ bool decode_object_initialized{false};
+};
+
+} // namespace AudioCore::OpusDecoder
diff --git a/src/audio_core/opus/decoder_manager.cpp b/src/audio_core/opus/decoder_manager.cpp
index 4a5382973..1464880a1 100644
--- a/src/audio_core/opus/decoder_manager.cpp
+++ b/src/audio_core/opus/decoder_manager.cpp
@@ -1,102 +1,102 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "audio_core/adsp/apps/opus/opus_decoder.h"
-#include "audio_core/opus/decoder_manager.h"
-#include "common/alignment.h"
-#include "core/core.h"
-
-namespace AudioCore::OpusDecoder {
-using namespace Service::Audio;
-
-namespace {
-bool IsValidChannelCount(u32 channel_count) {
- return channel_count == 1 || channel_count == 2;
-}
-
-bool IsValidMultiStreamChannelCount(u32 channel_count) {
- return channel_count > 0 && channel_count <= OpusStreamCountMax;
-}
-
-bool IsValidSampleRate(u32 sample_rate) {
- return sample_rate == 8'000 || sample_rate == 12'000 || sample_rate == 16'000 ||
- sample_rate == 24'000 || sample_rate == 48'000;
-}
-
-bool IsValidStreamCount(u32 channel_count, u32 total_stream_count, u32 stereo_stream_count) {
- return total_stream_count > 0 && stereo_stream_count > 0 &&
- stereo_stream_count <= total_stream_count &&
- total_stream_count + stereo_stream_count <= channel_count;
-}
-
-} // namespace
-
-OpusDecoderManager::OpusDecoderManager(Core::System& system_)
- : system{system_}, hardware_opus{system} {
- for (u32 i = 0; i < MaxChannels; i++) {
- required_workbuffer_sizes[i] = hardware_opus.GetWorkBufferSize(1 + i);
- }
-}
-
-Result OpusDecoderManager::GetWorkBufferSize(OpusParameters& params, u64& out_size) {
- OpusParametersEx ex{
- .sample_rate = params.sample_rate,
- .channel_count = params.channel_count,
- .use_large_frame_size = false,
- };
- R_RETURN(GetWorkBufferSizeExEx(ex, out_size));
-}
-
-Result OpusDecoderManager::GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size) {
- R_RETURN(GetWorkBufferSizeExEx(params, out_size));
-}
-
-Result OpusDecoderManager::GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size) {
- R_UNLESS(IsValidChannelCount(params.channel_count), ResultInvalidOpusChannelCount);
- R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate);
-
- auto work_buffer_size{required_workbuffer_sizes[params.channel_count - 1]};
- auto frame_size{params.use_large_frame_size ? 5760 : 1920};
- work_buffer_size +=
- Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 64);
- out_size = work_buffer_size + 0x600;
- R_SUCCEED();
-}
-
-Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params,
- u64& out_size) {
- OpusMultiStreamParametersEx ex{
- .sample_rate = params.sample_rate,
- .channel_count = params.channel_count,
- .total_stream_count = params.total_stream_count,
- .stereo_stream_count = params.stereo_stream_count,
- .use_large_frame_size = false,
- .mappings = {},
- };
- R_RETURN(GetWorkBufferSizeForMultiStreamExEx(ex, out_size));
-}
-
-Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params,
- u64& out_size) {
- R_RETURN(GetWorkBufferSizeForMultiStreamExEx(params, out_size));
-}
-
-Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params,
- u64& out_size) {
- R_UNLESS(IsValidMultiStreamChannelCount(params.channel_count), ResultInvalidOpusChannelCount);
- R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate);
- R_UNLESS(IsValidStreamCount(params.channel_count, params.total_stream_count,
- params.stereo_stream_count),
- ResultInvalidOpusSampleRate);
-
- auto work_buffer_size{hardware_opus.GetWorkBufferSizeForMultiStream(
- params.total_stream_count, params.stereo_stream_count)};
- auto frame_size{params.use_large_frame_size ? 5760 : 1920};
- work_buffer_size += Common::AlignUp(1500 * params.total_stream_count, 64);
- work_buffer_size +=
- Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 64);
- out_size = work_buffer_size;
- R_SUCCEED();
-}
-
-} // namespace AudioCore::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/adsp/apps/opus/opus_decoder.h"
+#include "audio_core/opus/decoder_manager.h"
+#include "common/alignment.h"
+#include "core/core.h"
+
+namespace AudioCore::OpusDecoder {
+using namespace Service::Audio;
+
+namespace {
+bool IsValidChannelCount(u32 channel_count) {
+ return channel_count == 1 || channel_count == 2;
+}
+
+bool IsValidMultiStreamChannelCount(u32 channel_count) {
+ return channel_count > 0 && channel_count <= OpusStreamCountMax;
+}
+
+bool IsValidSampleRate(u32 sample_rate) {
+ return sample_rate == 8'000 || sample_rate == 12'000 || sample_rate == 16'000 ||
+ sample_rate == 24'000 || sample_rate == 48'000;
+}
+
+bool IsValidStreamCount(u32 channel_count, u32 total_stream_count, u32 stereo_stream_count) {
+ return total_stream_count > 0 && static_cast<s32>(stereo_stream_count) >= 0 &&
+ stereo_stream_count <= total_stream_count &&
+ total_stream_count + stereo_stream_count <= channel_count;
+}
+
+} // namespace
+
+OpusDecoderManager::OpusDecoderManager(Core::System& system_)
+ : system{system_}, hardware_opus{system} {
+ for (u32 i = 0; i < MaxChannels; i++) {
+ required_workbuffer_sizes[i] = hardware_opus.GetWorkBufferSize(1 + i);
+ }
+}
+
+Result OpusDecoderManager::GetWorkBufferSize(OpusParameters& params, u64& out_size) {
+ OpusParametersEx ex{
+ .sample_rate = params.sample_rate,
+ .channel_count = params.channel_count,
+ .use_large_frame_size = false,
+ };
+ R_RETURN(GetWorkBufferSizeExEx(ex, out_size));
+}
+
+Result OpusDecoderManager::GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size) {
+ R_RETURN(GetWorkBufferSizeExEx(params, out_size));
+}
+
+Result OpusDecoderManager::GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size) {
+ R_UNLESS(IsValidChannelCount(params.channel_count), ResultInvalidOpusChannelCount);
+ R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate);
+
+ auto work_buffer_size{required_workbuffer_sizes[params.channel_count - 1]};
+ auto frame_size{params.use_large_frame_size ? 5760 : 1920};
+ work_buffer_size +=
+ Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 64);
+ out_size = work_buffer_size + 0x600;
+ R_SUCCEED();
+}
+
+Result OpusDecoderManager::GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params,
+ u64& out_size) {
+ OpusMultiStreamParametersEx ex{
+ .sample_rate = params.sample_rate,
+ .channel_count = params.channel_count,
+ .total_stream_count = params.total_stream_count,
+ .stereo_stream_count = params.stereo_stream_count,
+ .use_large_frame_size = false,
+ .mappings = {},
+ };
+ R_RETURN(GetWorkBufferSizeForMultiStreamExEx(ex, out_size));
+}
+
+Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params,
+ u64& out_size) {
+ R_RETURN(GetWorkBufferSizeForMultiStreamExEx(params, out_size));
+}
+
+Result OpusDecoderManager::GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params,
+ u64& out_size) {
+ R_UNLESS(IsValidMultiStreamChannelCount(params.channel_count), ResultInvalidOpusChannelCount);
+ R_UNLESS(IsValidSampleRate(params.sample_rate), ResultInvalidOpusSampleRate);
+ R_UNLESS(IsValidStreamCount(params.channel_count, params.total_stream_count,
+ params.stereo_stream_count),
+ ResultInvalidOpusSampleRate);
+
+ auto work_buffer_size{hardware_opus.GetWorkBufferSizeForMultiStream(
+ params.total_stream_count, params.stereo_stream_count)};
+ auto frame_size{params.use_large_frame_size ? 5760 : 1920};
+ work_buffer_size += Common::AlignUp(1500 * params.total_stream_count, 64);
+ work_buffer_size +=
+ Common::AlignUp((frame_size * params.channel_count) / (48'000 / params.sample_rate), 64);
+ out_size = work_buffer_size;
+ R_SUCCEED();
+}
+
+} // namespace AudioCore::OpusDecoder
diff --git a/src/audio_core/opus/decoder_manager.h b/src/audio_core/opus/decoder_manager.h
index 466e1967b..70ebc4bab 100644
--- a/src/audio_core/opus/decoder_manager.h
+++ b/src/audio_core/opus/decoder_manager.h
@@ -1,38 +1,38 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "audio_core/opus/hardware_opus.h"
-#include "audio_core/opus/parameters.h"
-#include "common/common_types.h"
-#include "core/hle/service/audio/errors.h"
-
-namespace Core {
-class System;
-}
-
-namespace AudioCore::OpusDecoder {
-
-class OpusDecoderManager {
-public:
- OpusDecoderManager(Core::System& system);
-
- HardwareOpus& GetHardwareOpus() {
- return hardware_opus;
- }
-
- Result GetWorkBufferSize(OpusParameters& params, u64& out_size);
- Result GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size);
- Result GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size);
- Result GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params, u64& out_size);
- Result GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params, u64& out_size);
- Result GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params, u64& out_size);
-
-private:
- Core::System& system;
- HardwareOpus hardware_opus;
- std::array<u64, MaxChannels> required_workbuffer_sizes{};
-};
-
-} // namespace AudioCore::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "audio_core/opus/hardware_opus.h"
+#include "audio_core/opus/parameters.h"
+#include "common/common_types.h"
+#include "core/hle/service/audio/errors.h"
+
+namespace Core {
+class System;
+}
+
+namespace AudioCore::OpusDecoder {
+
+class OpusDecoderManager {
+public:
+ OpusDecoderManager(Core::System& system);
+
+ HardwareOpus& GetHardwareOpus() {
+ return hardware_opus;
+ }
+
+ Result GetWorkBufferSize(OpusParameters& params, u64& out_size);
+ Result GetWorkBufferSizeEx(OpusParametersEx& params, u64& out_size);
+ Result GetWorkBufferSizeExEx(OpusParametersEx& params, u64& out_size);
+ Result GetWorkBufferSizeForMultiStream(OpusMultiStreamParameters& params, u64& out_size);
+ Result GetWorkBufferSizeForMultiStreamEx(OpusMultiStreamParametersEx& params, u64& out_size);
+ Result GetWorkBufferSizeForMultiStreamExEx(OpusMultiStreamParametersEx& params, u64& out_size);
+
+private:
+ Core::System& system;
+ HardwareOpus hardware_opus;
+ std::array<u64, MaxChannels> required_workbuffer_sizes{};
+};
+
+} // namespace AudioCore::OpusDecoder
diff --git a/src/audio_core/opus/hardware_opus.cpp b/src/audio_core/opus/hardware_opus.cpp
index d6544dcb0..5ff71ab2d 100644
--- a/src/audio_core/opus/hardware_opus.cpp
+++ b/src/audio_core/opus/hardware_opus.cpp
@@ -1,241 +1,241 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <array>
-
-#include "audio_core/audio_core.h"
-#include "audio_core/opus/hardware_opus.h"
-#include "core/core.h"
-
-namespace AudioCore::OpusDecoder {
-namespace {
-using namespace Service::Audio;
-
-static constexpr Result ResultCodeFromLibOpusErrorCode(u64 error_code) {
- s32 error{static_cast<s32>(error_code)};
- ASSERT(error <= OPUS_OK);
- switch (error) {
- case OPUS_ALLOC_FAIL:
- R_THROW(ResultLibOpusAllocFail);
- case OPUS_INVALID_STATE:
- R_THROW(ResultLibOpusInvalidState);
- case OPUS_UNIMPLEMENTED:
- R_THROW(ResultLibOpusUnimplemented);
- case OPUS_INVALID_PACKET:
- R_THROW(ResultLibOpusInvalidPacket);
- case OPUS_INTERNAL_ERROR:
- R_THROW(ResultLibOpusInternalError);
- case OPUS_BUFFER_TOO_SMALL:
- R_THROW(ResultBufferTooSmall);
- case OPUS_BAD_ARG:
- R_THROW(ResultLibOpusBadArg);
- case OPUS_OK:
- R_RETURN(ResultSuccess);
- }
- UNREACHABLE();
-}
-
-} // namespace
-
-HardwareOpus::HardwareOpus(Core::System& system_)
- : system{system_}, opus_decoder{system.AudioCore().ADSP().OpusDecoder()} {
- opus_decoder.SetSharedMemory(shared_memory);
-}
-
-u64 HardwareOpus::GetWorkBufferSize(u32 channel) {
- if (!opus_decoder.IsRunning()) {
- return 0;
- }
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = channel;
- opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::GetWorkBufferSize);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::GetWorkBufferSizeOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::GetWorkBufferSizeOK, msg);
- return 0;
- }
- return shared_memory.dsp_return_data[0];
-}
-
-u64 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = total_stream_count;
- shared_memory.host_send_data[1] = stereo_stream_count;
- opus_decoder.Send(ADSP::Direction::DSP,
- ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStream);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStreamOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStreamOK, msg);
- return 0;
- }
- return shared_memory.dsp_return_data[0];
-}
-
-Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer,
- u64 buffer_size) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = buffer_size;
- shared_memory.host_send_data[2] = sample_rate;
- shared_memory.host_send_data[3] = channel_count;
-
- opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::InitializeDecodeObject);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::InitializeDecodeObjectOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::InitializeDecodeObjectOK, msg);
- R_THROW(ResultInvalidOpusDSPReturnCode);
- }
-
- R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
-}
-
-Result HardwareOpus::InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
- u32 total_stream_count,
- u32 stereo_stream_count, void* mappings,
- void* buffer, u64 buffer_size) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = buffer_size;
- shared_memory.host_send_data[2] = sample_rate;
- shared_memory.host_send_data[3] = channel_count;
- shared_memory.host_send_data[4] = total_stream_count;
- shared_memory.host_send_data[5] = stereo_stream_count;
-
- ASSERT(channel_count <= MaxChannels);
- std::memcpy(shared_memory.channel_mapping.data(), mappings, channel_count * sizeof(u8));
-
- opus_decoder.Send(ADSP::Direction::DSP,
- ADSP::OpusDecoder::Message::InitializeMultiStreamDecodeObject);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::InitializeMultiStreamDecodeObjectOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::InitializeMultiStreamDecodeObjectOK, msg);
- R_THROW(ResultInvalidOpusDSPReturnCode);
- }
-
- R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
-}
-
-Result HardwareOpus::ShutdownDecodeObject(void* buffer, u64 buffer_size) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = buffer_size;
-
- opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::ShutdownDecodeObject);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- ASSERT_MSG(msg == ADSP::OpusDecoder::Message::ShutdownDecodeObjectOK,
- "Expected Opus shutdown code {}, got {}",
- ADSP::OpusDecoder::Message::ShutdownDecodeObjectOK, msg);
-
- R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
-}
-
-Result HardwareOpus::ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = buffer_size;
-
- opus_decoder.Send(ADSP::Direction::DSP,
- ADSP::OpusDecoder::Message::ShutdownMultiStreamDecodeObject);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- ASSERT_MSG(msg == ADSP::OpusDecoder::Message::ShutdownMultiStreamDecodeObjectOK,
- "Expected Opus shutdown code {}, got {}",
- ADSP::OpusDecoder::Message::ShutdownMultiStreamDecodeObjectOK, msg);
-
- R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
-}
-
-Result HardwareOpus::DecodeInterleaved(u32& out_sample_count, void* output_data,
- u64 output_data_size, u32 channel_count, void* input_data,
- u64 input_data_size, void* buffer, u64& out_time_taken,
- bool reset) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = (u64)input_data;
- shared_memory.host_send_data[2] = input_data_size;
- shared_memory.host_send_data[3] = (u64)output_data;
- shared_memory.host_send_data[4] = output_data_size;
- shared_memory.host_send_data[5] = 0;
- shared_memory.host_send_data[6] = reset;
-
- opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::DecodeInterleaved);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::DecodeInterleavedOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::DecodeInterleavedOK, msg);
- R_THROW(ResultInvalidOpusDSPReturnCode);
- }
-
- auto error_code{static_cast<s32>(shared_memory.dsp_return_data[0])};
- if (error_code == OPUS_OK) {
- out_sample_count = static_cast<u32>(shared_memory.dsp_return_data[1]);
- out_time_taken = 1000 * shared_memory.dsp_return_data[2];
- }
- R_RETURN(ResultCodeFromLibOpusErrorCode(error_code));
-}
-
-Result HardwareOpus::DecodeInterleavedForMultiStream(u32& out_sample_count, void* output_data,
- u64 output_data_size, u32 channel_count,
- void* input_data, u64 input_data_size,
- void* buffer, u64& out_time_taken,
- bool reset) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = (u64)input_data;
- shared_memory.host_send_data[2] = input_data_size;
- shared_memory.host_send_data[3] = (u64)output_data;
- shared_memory.host_send_data[4] = output_data_size;
- shared_memory.host_send_data[5] = 0;
- shared_memory.host_send_data[6] = reset;
-
- opus_decoder.Send(ADSP::Direction::DSP,
- ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStream);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStreamOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStreamOK, msg);
- R_THROW(ResultInvalidOpusDSPReturnCode);
- }
-
- auto error_code{static_cast<s32>(shared_memory.dsp_return_data[0])};
- if (error_code == OPUS_OK) {
- out_sample_count = static_cast<u32>(shared_memory.dsp_return_data[1]);
- out_time_taken = 1000 * shared_memory.dsp_return_data[2];
- }
- R_RETURN(ResultCodeFromLibOpusErrorCode(error_code));
-}
-
-Result HardwareOpus::MapMemory(void* buffer, u64 buffer_size) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = buffer_size;
-
- opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::MapMemory);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::MapMemoryOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::MapMemoryOK, msg);
- R_THROW(ResultInvalidOpusDSPReturnCode);
- }
- R_SUCCEED();
-}
-
-Result HardwareOpus::UnmapMemory(void* buffer, u64 buffer_size) {
- std::scoped_lock l{mutex};
- shared_memory.host_send_data[0] = (u64)buffer;
- shared_memory.host_send_data[1] = buffer_size;
-
- opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::UnmapMemory);
- auto msg = opus_decoder.Receive(ADSP::Direction::Host);
- if (msg != ADSP::OpusDecoder::Message::UnmapMemoryOK) {
- LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
- ADSP::OpusDecoder::Message::UnmapMemoryOK, msg);
- R_THROW(ResultInvalidOpusDSPReturnCode);
- }
- R_SUCCEED();
-}
-
-} // namespace AudioCore::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <array>
+
+#include "audio_core/audio_core.h"
+#include "audio_core/opus/hardware_opus.h"
+#include "core/core.h"
+
+namespace AudioCore::OpusDecoder {
+namespace {
+using namespace Service::Audio;
+
+static constexpr Result ResultCodeFromLibOpusErrorCode(u64 error_code) {
+ s32 error{static_cast<s32>(error_code)};
+ ASSERT(error <= OPUS_OK);
+ switch (error) {
+ case OPUS_ALLOC_FAIL:
+ R_THROW(ResultLibOpusAllocFail);
+ case OPUS_INVALID_STATE:
+ R_THROW(ResultLibOpusInvalidState);
+ case OPUS_UNIMPLEMENTED:
+ R_THROW(ResultLibOpusUnimplemented);
+ case OPUS_INVALID_PACKET:
+ R_THROW(ResultLibOpusInvalidPacket);
+ case OPUS_INTERNAL_ERROR:
+ R_THROW(ResultLibOpusInternalError);
+ case OPUS_BUFFER_TOO_SMALL:
+ R_THROW(ResultBufferTooSmall);
+ case OPUS_BAD_ARG:
+ R_THROW(ResultLibOpusBadArg);
+ case OPUS_OK:
+ R_RETURN(ResultSuccess);
+ }
+ UNREACHABLE();
+}
+
+} // namespace
+
+HardwareOpus::HardwareOpus(Core::System& system_)
+ : system{system_}, opus_decoder{system.AudioCore().ADSP().OpusDecoder()} {
+ opus_decoder.SetSharedMemory(shared_memory);
+}
+
+u64 HardwareOpus::GetWorkBufferSize(u32 channel) {
+ if (!opus_decoder.IsRunning()) {
+ return 0;
+ }
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = channel;
+ opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::GetWorkBufferSize);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::GetWorkBufferSizeOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::GetWorkBufferSizeOK, msg);
+ return 0;
+ }
+ return shared_memory.dsp_return_data[0];
+}
+
+u64 HardwareOpus::GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = total_stream_count;
+ shared_memory.host_send_data[1] = stereo_stream_count;
+ opus_decoder.Send(ADSP::Direction::DSP,
+ ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStream);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStreamOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::GetWorkBufferSizeForMultiStreamOK, msg);
+ return 0;
+ }
+ return shared_memory.dsp_return_data[0];
+}
+
+Result HardwareOpus::InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer,
+ u64 buffer_size) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = buffer_size;
+ shared_memory.host_send_data[2] = sample_rate;
+ shared_memory.host_send_data[3] = channel_count;
+
+ opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::InitializeDecodeObject);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::InitializeDecodeObjectOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::InitializeDecodeObjectOK, msg);
+ R_THROW(ResultInvalidOpusDSPReturnCode);
+ }
+
+ R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
+}
+
+Result HardwareOpus::InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
+ u32 total_stream_count,
+ u32 stereo_stream_count, void* mappings,
+ void* buffer, u64 buffer_size) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = buffer_size;
+ shared_memory.host_send_data[2] = sample_rate;
+ shared_memory.host_send_data[3] = channel_count;
+ shared_memory.host_send_data[4] = total_stream_count;
+ shared_memory.host_send_data[5] = stereo_stream_count;
+
+ ASSERT(channel_count <= MaxChannels);
+ std::memcpy(shared_memory.channel_mapping.data(), mappings, channel_count * sizeof(u8));
+
+ opus_decoder.Send(ADSP::Direction::DSP,
+ ADSP::OpusDecoder::Message::InitializeMultiStreamDecodeObject);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::InitializeMultiStreamDecodeObjectOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::InitializeMultiStreamDecodeObjectOK, msg);
+ R_THROW(ResultInvalidOpusDSPReturnCode);
+ }
+
+ R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
+}
+
+Result HardwareOpus::ShutdownDecodeObject(void* buffer, u64 buffer_size) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = buffer_size;
+
+ opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::ShutdownDecodeObject);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ ASSERT_MSG(msg == ADSP::OpusDecoder::Message::ShutdownDecodeObjectOK,
+ "Expected Opus shutdown code {}, got {}",
+ ADSP::OpusDecoder::Message::ShutdownDecodeObjectOK, msg);
+
+ R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
+}
+
+Result HardwareOpus::ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = buffer_size;
+
+ opus_decoder.Send(ADSP::Direction::DSP,
+ ADSP::OpusDecoder::Message::ShutdownMultiStreamDecodeObject);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ ASSERT_MSG(msg == ADSP::OpusDecoder::Message::ShutdownMultiStreamDecodeObjectOK,
+ "Expected Opus shutdown code {}, got {}",
+ ADSP::OpusDecoder::Message::ShutdownMultiStreamDecodeObjectOK, msg);
+
+ R_RETURN(ResultCodeFromLibOpusErrorCode(shared_memory.dsp_return_data[0]));
+}
+
+Result HardwareOpus::DecodeInterleaved(u32& out_sample_count, void* output_data,
+ u64 output_data_size, u32 channel_count, void* input_data,
+ u64 input_data_size, void* buffer, u64& out_time_taken,
+ bool reset) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = (u64)input_data;
+ shared_memory.host_send_data[2] = input_data_size;
+ shared_memory.host_send_data[3] = (u64)output_data;
+ shared_memory.host_send_data[4] = output_data_size;
+ shared_memory.host_send_data[5] = 0;
+ shared_memory.host_send_data[6] = reset;
+
+ opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::DecodeInterleaved);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::DecodeInterleavedOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::DecodeInterleavedOK, msg);
+ R_THROW(ResultInvalidOpusDSPReturnCode);
+ }
+
+ auto error_code{static_cast<s32>(shared_memory.dsp_return_data[0])};
+ if (error_code == OPUS_OK) {
+ out_sample_count = static_cast<u32>(shared_memory.dsp_return_data[1]);
+ out_time_taken = 1000 * shared_memory.dsp_return_data[2];
+ }
+ R_RETURN(ResultCodeFromLibOpusErrorCode(error_code));
+}
+
+Result HardwareOpus::DecodeInterleavedForMultiStream(u32& out_sample_count, void* output_data,
+ u64 output_data_size, u32 channel_count,
+ void* input_data, u64 input_data_size,
+ void* buffer, u64& out_time_taken,
+ bool reset) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = (u64)input_data;
+ shared_memory.host_send_data[2] = input_data_size;
+ shared_memory.host_send_data[3] = (u64)output_data;
+ shared_memory.host_send_data[4] = output_data_size;
+ shared_memory.host_send_data[5] = 0;
+ shared_memory.host_send_data[6] = reset;
+
+ opus_decoder.Send(ADSP::Direction::DSP,
+ ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStream);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStreamOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::DecodeInterleavedForMultiStreamOK, msg);
+ R_THROW(ResultInvalidOpusDSPReturnCode);
+ }
+
+ auto error_code{static_cast<s32>(shared_memory.dsp_return_data[0])};
+ if (error_code == OPUS_OK) {
+ out_sample_count = static_cast<u32>(shared_memory.dsp_return_data[1]);
+ out_time_taken = 1000 * shared_memory.dsp_return_data[2];
+ }
+ R_RETURN(ResultCodeFromLibOpusErrorCode(error_code));
+}
+
+Result HardwareOpus::MapMemory(void* buffer, u64 buffer_size) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = buffer_size;
+
+ opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::MapMemory);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::MapMemoryOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::MapMemoryOK, msg);
+ R_THROW(ResultInvalidOpusDSPReturnCode);
+ }
+ R_SUCCEED();
+}
+
+Result HardwareOpus::UnmapMemory(void* buffer, u64 buffer_size) {
+ std::scoped_lock l{mutex};
+ shared_memory.host_send_data[0] = (u64)buffer;
+ shared_memory.host_send_data[1] = buffer_size;
+
+ opus_decoder.Send(ADSP::Direction::DSP, ADSP::OpusDecoder::Message::UnmapMemory);
+ auto msg = opus_decoder.Receive(ADSP::Direction::Host);
+ if (msg != ADSP::OpusDecoder::Message::UnmapMemoryOK) {
+ LOG_ERROR(Service_Audio, "OpusDecoder returned invalid message. Expected {} got {}",
+ ADSP::OpusDecoder::Message::UnmapMemoryOK, msg);
+ R_THROW(ResultInvalidOpusDSPReturnCode);
+ }
+ R_SUCCEED();
+}
+
+} // namespace AudioCore::OpusDecoder
diff --git a/src/audio_core/opus/hardware_opus.h b/src/audio_core/opus/hardware_opus.h
index 7013a6b40..b10184baa 100644
--- a/src/audio_core/opus/hardware_opus.h
+++ b/src/audio_core/opus/hardware_opus.h
@@ -1,45 +1,45 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <mutex>
-#include <opus.h>
-
-#include "audio_core/adsp/apps/opus/opus_decoder.h"
-#include "audio_core/adsp/apps/opus/shared_memory.h"
-#include "audio_core/adsp/mailbox.h"
-#include "core/hle/service/audio/errors.h"
-
-namespace AudioCore::OpusDecoder {
-class HardwareOpus {
-public:
- HardwareOpus(Core::System& system);
-
- u64 GetWorkBufferSize(u32 channel);
- u64 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count);
-
- Result InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer,
- u64 buffer_size);
- Result InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
- u32 totaL_stream_count, u32 stereo_stream_count,
- void* mappings, void* buffer, u64 buffer_size);
- Result ShutdownDecodeObject(void* buffer, u64 buffer_size);
- Result ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size);
- Result DecodeInterleaved(u32& out_sample_count, void* output_data, u64 output_data_size,
- u32 channel_count, void* input_data, u64 input_data_size, void* buffer,
- u64& out_time_taken, bool reset);
- Result DecodeInterleavedForMultiStream(u32& out_sample_count, void* output_data,
- u64 output_data_size, u32 channel_count,
- void* input_data, u64 input_data_size, void* buffer,
- u64& out_time_taken, bool reset);
- Result MapMemory(void* buffer, u64 buffer_size);
- Result UnmapMemory(void* buffer, u64 buffer_size);
-
-private:
- Core::System& system;
- std::mutex mutex;
- ADSP::OpusDecoder::OpusDecoder& opus_decoder;
- ADSP::OpusDecoder::SharedMemory shared_memory;
-};
-} // namespace AudioCore::OpusDecoder
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <mutex>
+#include <opus.h>
+
+#include "audio_core/adsp/apps/opus/opus_decoder.h"
+#include "audio_core/adsp/apps/opus/shared_memory.h"
+#include "audio_core/adsp/mailbox.h"
+#include "core/hle/service/audio/errors.h"
+
+namespace AudioCore::OpusDecoder {
+class HardwareOpus {
+public:
+ HardwareOpus(Core::System& system);
+
+ u64 GetWorkBufferSize(u32 channel);
+ u64 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count);
+
+ Result InitializeDecodeObject(u32 sample_rate, u32 channel_count, void* buffer,
+ u64 buffer_size);
+ Result InitializeMultiStreamDecodeObject(u32 sample_rate, u32 channel_count,
+ u32 totaL_stream_count, u32 stereo_stream_count,
+ void* mappings, void* buffer, u64 buffer_size);
+ Result ShutdownDecodeObject(void* buffer, u64 buffer_size);
+ Result ShutdownMultiStreamDecodeObject(void* buffer, u64 buffer_size);
+ Result DecodeInterleaved(u32& out_sample_count, void* output_data, u64 output_data_size,
+ u32 channel_count, void* input_data, u64 input_data_size, void* buffer,
+ u64& out_time_taken, bool reset);
+ Result DecodeInterleavedForMultiStream(u32& out_sample_count, void* output_data,
+ u64 output_data_size, u32 channel_count,
+ void* input_data, u64 input_data_size, void* buffer,
+ u64& out_time_taken, bool reset);
+ Result MapMemory(void* buffer, u64 buffer_size);
+ Result UnmapMemory(void* buffer, u64 buffer_size);
+
+private:
+ Core::System& system;
+ std::mutex mutex;
+ ADSP::OpusDecoder::OpusDecoder& opus_decoder;
+ ADSP::OpusDecoder::SharedMemory shared_memory;
+};
+} // namespace AudioCore::OpusDecoder
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp
index bbb598bc5..51a23fe15 100644
--- a/src/audio_core/sink/cubeb_sink.cpp
+++ b/src/audio_core/sink/cubeb_sink.cpp
@@ -146,7 +146,7 @@ public:
return;
}
- paused = true;
+ SignalPause();
if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
}
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index 7b89151de..96e0efce2 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -111,7 +111,7 @@ public:
if (device == 0 || paused) {
return;
}
- paused = true;
+ SignalPause();
SDL_PauseAudioDevice(device, 1);
}
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index d66d04fae..2a09db599 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -282,11 +282,19 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
void SinkStream::WaitFreeSpace(std::stop_token stop_token) {
std::unique_lock lk{release_mutex};
release_cv.wait_for(lk, std::chrono::milliseconds(5),
- [this]() { return queued_buffers < max_queue_size; });
+ [this]() { return paused || queued_buffers < max_queue_size; });
if (queued_buffers > max_queue_size + 3) {
Common::CondvarWait(release_cv, lk, stop_token,
- [this] { return queued_buffers < max_queue_size; });
+ [this] { return paused || queued_buffers < max_queue_size; });
}
}
+void SinkStream::SignalPause() {
+ {
+ std::scoped_lock lk{release_mutex};
+ paused = true;
+ }
+ release_cv.notify_one();
+}
+
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h
index 6a4996ca3..f2ccd19b8 100644
--- a/src/audio_core/sink/sink_stream.h
+++ b/src/audio_core/sink/sink_stream.h
@@ -214,6 +214,12 @@ public:
void WaitFreeSpace(std::stop_token stop_token);
protected:
+ /**
+ * Unblocks the ADSP if the stream is paused.
+ */
+ void SignalPause();
+
+protected:
/// Core system
Core::System& system;
/// Type of this stream
diff --git a/src/common/arm64/native_clock.cpp b/src/common/arm64/native_clock.cpp
index 88fdba527..f437d7187 100644
--- a/src/common/arm64/native_clock.cpp
+++ b/src/common/arm64/native_clock.cpp
@@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#ifdef ANDROID
+#include <sys/system_properties.h>
+#endif
#include "common/arm64/native_clock.h"
namespace Common::Arm64 {
@@ -65,7 +68,23 @@ bool NativeClock::IsNative() const {
u64 NativeClock::GetHostCNTFRQ() {
u64 cntfrq_el0 = 0;
- asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
+ std::string_view board{""};
+#ifdef ANDROID
+ char buffer[PROP_VALUE_MAX];
+ int len{__system_property_get("ro.product.board", buffer)};
+ board = std::string_view(buffer, static_cast<size_t>(len));
+#endif
+ if (board == "s5e9925") { // Exynos 2200
+ cntfrq_el0 = 25600000;
+ } else if (board == "exynos2100") { // Exynos 2100
+ cntfrq_el0 = 26000000;
+ } else if (board == "exynos9810") { // Exynos 9810
+ cntfrq_el0 = 26000000;
+ } else if (board == "s5e8825") { // Exynos 1280
+ cntfrq_el0 = 26000000;
+ } else {
+ asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
+ }
return cntfrq_el0;
}
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp
index 4b1690269..166dc3dce 100644
--- a/src/common/page_table.cpp
+++ b/src/common/page_table.cpp
@@ -9,12 +9,12 @@ PageTable::PageTable() = default;
PageTable::~PageTable() noexcept = default;
-bool PageTable::BeginTraversal(TraversalEntry& out_entry, TraversalContext& out_context,
- u64 address) const {
+bool PageTable::BeginTraversal(TraversalEntry* out_entry, TraversalContext* out_context,
+ Common::ProcessAddress address) const {
// Setup invalid defaults.
- out_entry.phys_addr = 0;
- out_entry.block_size = page_size;
- out_context.next_page = 0;
+ out_entry->phys_addr = 0;
+ out_entry->block_size = page_size;
+ out_context->next_page = 0;
// Validate that we can read the actual entry.
const auto page = address / page_size;
@@ -29,20 +29,20 @@ bool PageTable::BeginTraversal(TraversalEntry& out_entry, TraversalContext& out_
}
// Populate the results.
- out_entry.phys_addr = phys_addr + address;
- out_context.next_page = page + 1;
- out_context.next_offset = address + page_size;
+ out_entry->phys_addr = phys_addr + GetInteger(address);
+ out_context->next_page = page + 1;
+ out_context->next_offset = GetInteger(address) + page_size;
return true;
}
-bool PageTable::ContinueTraversal(TraversalEntry& out_entry, TraversalContext& context) const {
+bool PageTable::ContinueTraversal(TraversalEntry* out_entry, TraversalContext* context) const {
// Setup invalid defaults.
- out_entry.phys_addr = 0;
- out_entry.block_size = page_size;
+ out_entry->phys_addr = 0;
+ out_entry->block_size = page_size;
// Validate that we can read the actual entry.
- const auto page = context.next_page;
+ const auto page = context->next_page;
if (page >= backing_addr.size()) {
return false;
}
@@ -54,9 +54,9 @@ bool PageTable::ContinueTraversal(TraversalEntry& out_entry, TraversalContext& c
}
// Populate the results.
- out_entry.phys_addr = phys_addr + context.next_offset;
- context.next_page = page + 1;
- context.next_offset += page_size;
+ out_entry->phys_addr = phys_addr + context->next_offset;
+ context->next_page = page + 1;
+ context->next_offset += page_size;
return true;
}
diff --git a/src/common/page_table.h b/src/common/page_table.h
index e653d52ad..5340f7d86 100644
--- a/src/common/page_table.h
+++ b/src/common/page_table.h
@@ -6,6 +6,7 @@
#include <atomic>
#include "common/common_types.h"
+#include "common/typed_address.h"
#include "common/virtual_buffer.h"
namespace Common {
@@ -100,9 +101,9 @@ struct PageTable {
PageTable(PageTable&&) noexcept = default;
PageTable& operator=(PageTable&&) noexcept = default;
- bool BeginTraversal(TraversalEntry& out_entry, TraversalContext& out_context,
- u64 address) const;
- bool ContinueTraversal(TraversalEntry& out_entry, TraversalContext& context) const;
+ bool BeginTraversal(TraversalEntry* out_entry, TraversalContext* out_context,
+ Common::ProcessAddress address) const;
+ bool ContinueTraversal(TraversalEntry* out_entry, TraversalContext* context) const;
/**
* Resizes the page table to be able to accommodate enough pages within
@@ -117,6 +118,16 @@ struct PageTable {
return current_address_space_width_in_bits;
}
+ bool GetPhysicalAddress(Common::PhysicalAddress* out_phys_addr,
+ Common::ProcessAddress virt_addr) const {
+ if (virt_addr > (1ULL << this->GetAddressSpaceBits())) {
+ return false;
+ }
+
+ *out_phys_addr = backing_addr[virt_addr / page_size] + GetInteger(virt_addr);
+ return true;
+ }
+
/**
* Vector of memory pointers backing each page. An entry can only be non-null if the
* corresponding attribute element is of type `Memory`.
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 98b43e49c..a10131eb2 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -203,10 +203,12 @@ const char* TranslateCategory(Category category) {
case Category::Ui:
case Category::UiGeneral:
return "UI";
+ case Category::UiAudio:
+ return "UiAudio";
case Category::UiLayout:
- return "UiLayout";
+ return "UILayout";
case Category::UiGameList:
- return "UiGameList";
+ return "UIGameList";
case Category::Screenshots:
return "Screenshots";
case Category::Shortcuts:
diff --git a/src/common/settings.h b/src/common/settings.h
index 9317075f7..b929fd957 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -153,7 +153,7 @@ struct Values {
true,
true};
Setting<bool, false> audio_muted{
- linkage, false, "audio_muted", Category::Audio, Specialization::Default, false, true};
+ linkage, false, "audio_muted", Category::Audio, Specialization::Default, true, true};
Setting<bool, false> dump_audio_commands{
linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false};
@@ -232,7 +232,11 @@ struct Values {
SwitchableSetting<bool> use_asynchronous_gpu_emulation{
linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer};
SwitchableSetting<AstcDecodeMode, true> accelerate_astc{linkage,
+#ifdef ANDROID
+ AstcDecodeMode::Cpu,
+#else
AstcDecodeMode::Gpu,
+#endif
AstcDecodeMode::Cpu,
AstcDecodeMode::CpuAsynchronous,
"accelerate_astc",
@@ -304,7 +308,11 @@ struct Values {
linkage, 0, "bg_blue", Category::Renderer, Specialization::Default, true, true};
SwitchableSetting<GpuAccuracy, true> gpu_accuracy{linkage,
+#ifdef ANDROID
+ GpuAccuracy::Normal,
+#else
GpuAccuracy::High,
+#endif
GpuAccuracy::Normal,
GpuAccuracy::Extreme,
"gpu_accuracy",
@@ -313,20 +321,38 @@ struct Values {
true,
true};
GpuAccuracy current_gpu_accuracy{GpuAccuracy::High};
- SwitchableSetting<AnisotropyMode, true> max_anisotropy{
- linkage, AnisotropyMode::Automatic, AnisotropyMode::Automatic, AnisotropyMode::X16,
- "max_anisotropy", Category::RendererAdvanced};
+ SwitchableSetting<AnisotropyMode, true> max_anisotropy{linkage,
+#ifdef ANDROID
+ AnisotropyMode::Default,
+#else
+ AnisotropyMode::Automatic,
+#endif
+ AnisotropyMode::Automatic,
+ AnisotropyMode::X16,
+ "max_anisotropy",
+ Category::RendererAdvanced};
SwitchableSetting<AstcRecompression, true> astc_recompression{linkage,
AstcRecompression::Uncompressed,
AstcRecompression::Uncompressed,
AstcRecompression::Bc3,
"astc_recompression",
Category::RendererAdvanced};
- SwitchableSetting<bool> async_presentation{linkage, false, "async_presentation",
- Category::RendererAdvanced};
+ SwitchableSetting<bool> async_presentation{linkage,
+#ifdef ANDROID
+ true,
+#else
+ false,
+#endif
+ "async_presentation", Category::RendererAdvanced};
SwitchableSetting<bool> renderer_force_max_clock{linkage, false, "force_max_clock",
Category::RendererAdvanced};
- SwitchableSetting<bool> use_reactive_flushing{linkage, true, "use_reactive_flushing",
+ SwitchableSetting<bool> use_reactive_flushing{linkage,
+#ifdef ANDROID
+ false,
+#else
+ true,
+#endif
+ "use_reactive_flushing",
Category::RendererAdvanced};
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererAdvanced};
@@ -358,6 +384,8 @@ struct Values {
Category::RendererDebug};
// TODO: remove this once AMDVLK supports VK_EXT_depth_bias_control
bool renderer_amdvlk_depth_bias_workaround{};
+ Setting<bool> disable_buffer_reorder{linkage, false, "disable_buffer_reorder",
+ Category::RendererDebug};
// System
SwitchableSetting<Language, true> language_index{linkage,
@@ -390,7 +418,11 @@ struct Values {
Setting<s32> current_user{linkage, 0, "current_user", Category::System};
SwitchableSetting<ConsoleMode> use_docked_mode{linkage,
+#ifdef ANDROID
+ ConsoleMode::Handheld,
+#else
ConsoleMode::Docked,
+#endif
"use_docked_mode",
Category::System,
Specialization::Radio,
diff --git a/src/common/settings_common.h b/src/common/settings_common.h
index 1800ab10d..7943223eb 100644
--- a/src/common/settings_common.h
+++ b/src/common/settings_common.h
@@ -32,6 +32,7 @@ enum class Category : u32 {
AddOns,
Controls,
Ui,
+ UiAudio,
UiGeneral,
UiLayout,
UiGameList,
diff --git a/src/common/settings_input.cpp b/src/common/settings_input.cpp
index 0a6eea3cf..a6007e7b2 100644
--- a/src/common/settings_input.cpp
+++ b/src/common/settings_input.cpp
@@ -6,10 +6,11 @@
namespace Settings {
namespace NativeButton {
const std::array<const char*, NumButtons> mapping = {{
- "button_a", "button_b", "button_x", "button_y", "button_lstick",
- "button_rstick", "button_l", "button_r", "button_zl", "button_zr",
- "button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
- "button_ddown", "button_sl", "button_sr", "button_home", "button_screenshot",
+ "button_a", "button_b", "button_x", "button_y", "button_lstick",
+ "button_rstick", "button_l", "button_r", "button_zl", "button_zr",
+ "button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
+ "button_ddown", "button_slleft", "button_srleft", "button_home", "button_screenshot",
+ "button_slright", "button_srright",
}};
}
diff --git a/src/common/settings_input.h b/src/common/settings_input.h
index 46f38c703..53a95ef8f 100644
--- a/src/common/settings_input.h
+++ b/src/common/settings_input.h
@@ -29,12 +29,15 @@ enum Values : int {
DRight,
DDown,
- SL,
- SR,
+ SLLeft,
+ SRLeft,
Home,
Screenshot,
+ SLRight,
+ SRRight,
+
NumButtons,
};
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e4f499135..66c10fc3f 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -271,8 +271,9 @@ add_library(core STATIC
hle/kernel/k_page_heap.h
hle/kernel/k_page_group.cpp
hle/kernel/k_page_group.h
- hle/kernel/k_page_table.cpp
hle/kernel/k_page_table.h
+ hle/kernel/k_page_table_base.cpp
+ hle/kernel/k_page_table_base.h
hle/kernel/k_page_table_manager.h
hle/kernel/k_page_table_slab_heap.h
hle/kernel/k_port.cpp
@@ -280,6 +281,7 @@ add_library(core STATIC
hle/kernel/k_priority_queue.h
hle/kernel/k_process.cpp
hle/kernel/k_process.h
+ hle/kernel/k_process_page_table.h
hle/kernel/k_readable_event.cpp
hle/kernel/k_readable_event.h
hle/kernel/k_resource_limit.cpp
@@ -330,8 +332,6 @@ add_library(core STATIC
hle/kernel/physical_core.cpp
hle/kernel/physical_core.h
hle/kernel/physical_memory.h
- hle/kernel/process_capability.cpp
- hle/kernel/process_capability.h
hle/kernel/slab_helpers.h
hle/kernel/svc.cpp
hle/kernel/svc.h
@@ -521,17 +521,28 @@ add_library(core STATIC
hle/service/grc/grc.h
hle/service/hid/hid.cpp
hle/service/hid/hid.h
+ hle/service/hid/hid_debug_server.cpp
+ hle/service/hid/hid_debug_server.h
+ hle/service/hid/hid_firmware_settings.cpp
+ hle/service/hid/hid_firmware_settings.h
+ hle/service/hid/hid_server.cpp
+ hle/service/hid/hid_server.h
+ hle/service/hid/hid_system_server.cpp
+ hle/service/hid/hid_system_server.h
+ hle/service/hid/hid_util.h
hle/service/hid/hidbus.cpp
hle/service/hid/hidbus.h
hle/service/hid/irs.cpp
hle/service/hid/irs.h
hle/service/hid/irs_ring_lifo.h
+ hle/service/hid/resource_manager.cpp
+ hle/service/hid/resource_manager.h
hle/service/hid/ring_lifo.h
hle/service/hid/xcd.cpp
hle/service/hid/xcd.h
hle/service/hid/errors.h
- hle/service/hid/controllers/console_sixaxis.cpp
- hle/service/hid/controllers/console_sixaxis.h
+ hle/service/hid/controllers/console_six_axis.cpp
+ hle/service/hid/controllers/console_six_axis.h
hle/service/hid/controllers/controller_base.cpp
hle/service/hid/controllers/controller_base.h
hle/service/hid/controllers/debug_pad.cpp
@@ -546,6 +557,10 @@ add_library(core STATIC
hle/service/hid/controllers/npad.h
hle/service/hid/controllers/palma.cpp
hle/service/hid/controllers/palma.h
+ hle/service/hid/controllers/seven_six_axis.cpp
+ hle/service/hid/controllers/seven_six_axis.h
+ hle/service/hid/controllers/six_axis.cpp
+ hle/service/hid/controllers/six_axis.h
hle/service/hid/controllers/stubbed.cpp
hle/service/hid/controllers/stubbed.h
hle/service/hid/controllers/touchscreen.cpp
@@ -715,6 +730,7 @@ add_library(core STATIC
hle/service/nvnflinger/producer_listener.h
hle/service/nvnflinger/status.h
hle/service/nvnflinger/ui/fence.h
+ hle/service/nvnflinger/ui/graphic_buffer.cpp
hle/service/nvnflinger/ui/graphic_buffer.h
hle/service/nvnflinger/window.h
hle/service/olsc/olsc.cpp
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 5e27dde58..558fba5bd 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -153,6 +153,14 @@ void ARM_Interface::Run() {
Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())};
HaltReason hr{};
+ // If the thread is scheduled for termination, exit the thread.
+ if (current_thread->HasDpc()) {
+ if (current_thread->IsTerminationRequested()) {
+ current_thread->Exit();
+ UNREACHABLE();
+ }
+ }
+
// Notify the debugger and go to sleep if a step was performed
// and this thread has been scheduled again.
if (current_thread->GetStepState() == StepState::StepPerformed) {
@@ -174,14 +182,6 @@ void ARM_Interface::Run() {
}
system.ExitCPUProfile();
- // If the thread is scheduled for termination, exit the thread.
- if (current_thread->HasDpc()) {
- if (current_thread->IsTerminationRequested()) {
- current_thread->Exit();
- UNREACHABLE();
- }
- }
-
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) {
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index e671b270f..d6b5abc68 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -76,6 +76,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
}
void CoreTiming::ClearPendingEvents() {
+ std::scoped_lock lock{basic_lock};
event_queue.clear();
}
@@ -113,6 +114,7 @@ bool CoreTiming::IsRunning() const {
}
bool CoreTiming::HasPendingEvents() const {
+ std::scoped_lock lock{basic_lock};
return !(wait_set && event_queue.empty());
}
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 26a8b93a7..21548f0a9 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -161,7 +161,7 @@ private:
std::shared_ptr<EventType> ev_lost;
Common::Event event{};
Common::Event pause_event{};
- std::mutex basic_lock;
+ mutable std::mutex basic_lock;
std::mutex advance_lock;
std::unique_ptr<std::jthread> timer_thread;
std::atomic<bool> paused{};
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index 6f5f5156b..148dd3e39 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -562,6 +562,120 @@ static std::string PaginateBuffer(std::string_view buffer, std::string_view requ
}
}
+static VAddr GetModuleEnd(Kernel::KProcessPageTable& page_table, VAddr base) {
+ Kernel::KMemoryInfo mem_info;
+ Kernel::Svc::MemoryInfo svc_mem_info;
+ Kernel::Svc::PageInfo page_info;
+ VAddr cur_addr{base};
+
+ // Expect: r-x Code (.text)
+ R_ASSERT(page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
+ svc_mem_info = mem_info.GetSvcMemoryInfo();
+ cur_addr = svc_mem_info.base_address + svc_mem_info.size;
+ if (svc_mem_info.state != Kernel::Svc::MemoryState::Code ||
+ svc_mem_info.permission != Kernel::Svc::MemoryPermission::ReadExecute) {
+ return cur_addr - 1;
+ }
+
+ // Expect: r-- Code (.rodata)
+ R_ASSERT(page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
+ svc_mem_info = mem_info.GetSvcMemoryInfo();
+ cur_addr = svc_mem_info.base_address + svc_mem_info.size;
+ if (svc_mem_info.state != Kernel::Svc::MemoryState::Code ||
+ svc_mem_info.permission != Kernel::Svc::MemoryPermission::Read) {
+ return cur_addr - 1;
+ }
+
+ // Expect: rw- CodeData (.data)
+ R_ASSERT(page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
+ svc_mem_info = mem_info.GetSvcMemoryInfo();
+ cur_addr = svc_mem_info.base_address + svc_mem_info.size;
+ return cur_addr - 1;
+}
+
+static Loader::AppLoader::Modules FindModules(Core::System& system) {
+ Loader::AppLoader::Modules modules;
+
+ auto& page_table = system.ApplicationProcess()->GetPageTable();
+ auto& memory = system.ApplicationMemory();
+ VAddr cur_addr = 0;
+
+ // Look for executable sections in Code or AliasCode regions.
+ while (true) {
+ Kernel::KMemoryInfo mem_info{};
+ Kernel::Svc::PageInfo page_info{};
+ R_ASSERT(
+ page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
+ auto svc_mem_info = mem_info.GetSvcMemoryInfo();
+
+ if (svc_mem_info.permission == Kernel::Svc::MemoryPermission::ReadExecute &&
+ (svc_mem_info.state == Kernel::Svc::MemoryState::Code ||
+ svc_mem_info.state == Kernel::Svc::MemoryState::AliasCode)) {
+ // Try to read the module name from its path.
+ constexpr s32 PathLengthMax = 0x200;
+ struct {
+ u32 zero;
+ s32 path_length;
+ std::array<char, PathLengthMax> path;
+ } module_path;
+
+ if (memory.ReadBlock(svc_mem_info.base_address + svc_mem_info.size, &module_path,
+ sizeof(module_path))) {
+ if (module_path.zero == 0 && module_path.path_length > 0) {
+ // Truncate module name.
+ module_path.path[PathLengthMax - 1] = '\0';
+
+ // Ignore leading directories.
+ char* path_pointer = module_path.path.data();
+
+ for (s32 i = 0; i < std::min(PathLengthMax, module_path.path_length) &&
+ module_path.path[i] != '\0';
+ i++) {
+ if (module_path.path[i] == '/' || module_path.path[i] == '\\') {
+ path_pointer = module_path.path.data() + i + 1;
+ }
+ }
+
+ // Insert output.
+ modules.emplace(svc_mem_info.base_address, path_pointer);
+ }
+ }
+ }
+
+ // Check if we're done.
+ const uintptr_t next_address = svc_mem_info.base_address + svc_mem_info.size;
+ if (next_address <= cur_addr) {
+ break;
+ }
+
+ cur_addr = next_address;
+ }
+
+ return modules;
+}
+
+static VAddr FindMainModuleEntrypoint(Core::System& system) {
+ Loader::AppLoader::Modules modules;
+ system.GetAppLoader().ReadNSOModules(modules);
+
+ // Do we have a module named main?
+ const auto main = std::find_if(modules.begin(), modules.end(),
+ [](const auto& key) { return key.second == "main"; });
+
+ if (main != modules.end()) {
+ return main->first;
+ }
+
+ // Do we have any loaded executable sections?
+ modules = FindModules(system);
+ if (!modules.empty()) {
+ return modules.begin()->first;
+ }
+
+ // As a last resort, use the start of the code region.
+ return GetInteger(system.ApplicationProcess()->GetPageTable().GetCodeRegionStart());
+}
+
void GDBStub::HandleQuery(std::string_view command) {
if (command.starts_with("TStatus")) {
// no tracepoint support
@@ -573,21 +687,10 @@ void GDBStub::HandleQuery(std::string_view command) {
const auto target_xml{arch->GetTargetXML()};
SendReply(PaginateBuffer(target_xml, command.substr(30)));
} else if (command.starts_with("Offsets")) {
- Loader::AppLoader::Modules modules;
- system.GetAppLoader().ReadNSOModules(modules);
-
- const auto main = std::find_if(modules.begin(), modules.end(),
- [](const auto& key) { return key.second == "main"; });
- if (main != modules.end()) {
- SendReply(fmt::format("TextSeg={:x}", main->first));
- } else {
- SendReply(fmt::format(
- "TextSeg={:x}",
- GetInteger(system.ApplicationProcess()->GetPageTable().GetCodeRegionStart())));
- }
+ const auto main_offset = FindMainModuleEntrypoint(system);
+ SendReply(fmt::format("TextSeg={:x}", main_offset));
} else if (command.starts_with("Xfer:libraries:read::")) {
- Loader::AppLoader::Modules modules;
- system.GetAppLoader().ReadNSOModules(modules);
+ auto modules = FindModules(system);
std::string buffer;
buffer += R"(<?xml version="1.0"?>)";
@@ -727,32 +830,6 @@ static constexpr const char* GetMemoryPermissionString(const Kernel::Svc::Memory
}
}
-static VAddr GetModuleEnd(Kernel::KPageTable& page_table, VAddr base) {
- Kernel::Svc::MemoryInfo mem_info;
- VAddr cur_addr{base};
-
- // Expect: r-x Code (.text)
- mem_info = page_table.QueryInfo(cur_addr).GetSvcMemoryInfo();
- cur_addr = mem_info.base_address + mem_info.size;
- if (mem_info.state != Kernel::Svc::MemoryState::Code ||
- mem_info.permission != Kernel::Svc::MemoryPermission::ReadExecute) {
- return cur_addr - 1;
- }
-
- // Expect: r-- Code (.rodata)
- mem_info = page_table.QueryInfo(cur_addr).GetSvcMemoryInfo();
- cur_addr = mem_info.base_address + mem_info.size;
- if (mem_info.state != Kernel::Svc::MemoryState::Code ||
- mem_info.permission != Kernel::Svc::MemoryPermission::Read) {
- return cur_addr - 1;
- }
-
- // Expect: rw- CodeData (.data)
- mem_info = page_table.QueryInfo(cur_addr).GetSvcMemoryInfo();
- cur_addr = mem_info.base_address + mem_info.size;
- return cur_addr - 1;
-}
-
void GDBStub::HandleRcmd(const std::vector<u8>& command) {
std::string_view command_str{reinterpret_cast<const char*>(&command[0]), command.size()};
std::string reply;
@@ -767,7 +844,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
if (command_str == "get fastmem") {
if (Settings::IsFastmemEnabled()) {
- const auto& impl = page_table.PageTableImpl();
+ const auto& impl = page_table.GetImpl();
const auto region = reinterpret_cast<uintptr_t>(impl.fastmem_arena);
const auto region_bits = impl.current_address_space_width_in_bits;
const auto region_size = 1ULL << region_bits;
@@ -779,26 +856,27 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
reply = "Fastmem is not enabled.\n";
}
} else if (command_str == "get info") {
- Loader::AppLoader::Modules modules;
- system.GetAppLoader().ReadNSOModules(modules);
+ auto modules = FindModules(system);
reply = fmt::format("Process: {:#x} ({})\n"
"Program Id: {:#018x}\n",
process->GetProcessId(), process->GetName(), process->GetProgramId());
- reply += fmt::format("Layout:\n"
- " Alias: {:#012x} - {:#012x}\n"
- " Heap: {:#012x} - {:#012x}\n"
- " Aslr: {:#012x} - {:#012x}\n"
- " Stack: {:#012x} - {:#012x}\n"
- "Modules:\n",
- GetInteger(page_table.GetAliasRegionStart()),
- GetInteger(page_table.GetAliasRegionEnd()),
- GetInteger(page_table.GetHeapRegionStart()),
- GetInteger(page_table.GetHeapRegionEnd()),
- GetInteger(page_table.GetAliasCodeRegionStart()),
- GetInteger(page_table.GetAliasCodeRegionEnd()),
- GetInteger(page_table.GetStackRegionStart()),
- GetInteger(page_table.GetStackRegionEnd()));
+ reply += fmt::format(
+ "Layout:\n"
+ " Alias: {:#012x} - {:#012x}\n"
+ " Heap: {:#012x} - {:#012x}\n"
+ " Aslr: {:#012x} - {:#012x}\n"
+ " Stack: {:#012x} - {:#012x}\n"
+ "Modules:\n",
+ GetInteger(page_table.GetAliasRegionStart()),
+ GetInteger(page_table.GetAliasRegionStart()) + page_table.GetAliasRegionSize() - 1,
+ GetInteger(page_table.GetHeapRegionStart()),
+ GetInteger(page_table.GetHeapRegionStart()) + page_table.GetHeapRegionSize() - 1,
+ GetInteger(page_table.GetAliasCodeRegionStart()),
+ GetInteger(page_table.GetAliasCodeRegionStart()) + page_table.GetAliasCodeRegionSize() -
+ 1,
+ GetInteger(page_table.GetStackRegionStart()),
+ GetInteger(page_table.GetStackRegionStart()) + page_table.GetStackRegionSize() - 1);
for (const auto& [vaddr, name] : modules) {
reply += fmt::format(" {:#012x} - {:#012x} {}\n", vaddr,
@@ -811,27 +889,34 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
while (true) {
using MemoryAttribute = Kernel::Svc::MemoryAttribute;
- auto mem_info = page_table.QueryInfo(cur_addr).GetSvcMemoryInfo();
-
- if (mem_info.state != Kernel::Svc::MemoryState::Inaccessible ||
- mem_info.base_address + mem_info.size - 1 != std::numeric_limits<u64>::max()) {
- const char* state = GetMemoryStateName(mem_info.state);
- const char* perm = GetMemoryPermissionString(mem_info);
-
- const char l = True(mem_info.attribute & MemoryAttribute::Locked) ? 'L' : '-';
- const char i = True(mem_info.attribute & MemoryAttribute::IpcLocked) ? 'I' : '-';
- const char d = True(mem_info.attribute & MemoryAttribute::DeviceShared) ? 'D' : '-';
- const char u = True(mem_info.attribute & MemoryAttribute::Uncached) ? 'U' : '-';
+ Kernel::KMemoryInfo mem_info{};
+ Kernel::Svc::PageInfo page_info{};
+ R_ASSERT(page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info),
+ cur_addr));
+ auto svc_mem_info = mem_info.GetSvcMemoryInfo();
+
+ if (svc_mem_info.state != Kernel::Svc::MemoryState::Inaccessible ||
+ svc_mem_info.base_address + svc_mem_info.size - 1 !=
+ std::numeric_limits<u64>::max()) {
+ const char* state = GetMemoryStateName(svc_mem_info.state);
+ const char* perm = GetMemoryPermissionString(svc_mem_info);
+
+ const char l = True(svc_mem_info.attribute & MemoryAttribute::Locked) ? 'L' : '-';
+ const char i =
+ True(svc_mem_info.attribute & MemoryAttribute::IpcLocked) ? 'I' : '-';
+ const char d =
+ True(svc_mem_info.attribute & MemoryAttribute::DeviceShared) ? 'D' : '-';
+ const char u = True(svc_mem_info.attribute & MemoryAttribute::Uncached) ? 'U' : '-';
const char p =
- True(mem_info.attribute & MemoryAttribute::PermissionLocked) ? 'P' : '-';
+ True(svc_mem_info.attribute & MemoryAttribute::PermissionLocked) ? 'P' : '-';
- reply += fmt::format(" {:#012x} - {:#012x} {} {} {}{}{}{}{} [{}, {}]\n",
- mem_info.base_address,
- mem_info.base_address + mem_info.size - 1, perm, state, l, i,
- d, u, p, mem_info.ipc_count, mem_info.device_count);
+ reply += fmt::format(
+ " {:#012x} - {:#012x} {} {} {}{}{}{}{} [{}, {}]\n", svc_mem_info.base_address,
+ svc_mem_info.base_address + svc_mem_info.size - 1, perm, state, l, i, d, u, p,
+ svc_mem_info.ipc_count, svc_mem_info.device_count);
}
- const uintptr_t next_address = mem_info.base_address + mem_info.size;
+ const uintptr_t next_address = svc_mem_info.base_address + svc_mem_info.size;
if (next_address <= cur_addr) {
break;
}
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp
index 1c580de57..1eb1f439a 100644
--- a/src/core/file_sys/romfs.cpp
+++ b/src/core/file_sys/romfs.cpp
@@ -35,13 +35,14 @@ struct RomFSHeader {
static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size.");
struct DirectoryEntry {
+ u32_le parent;
u32_le sibling;
u32_le child_dir;
u32_le child_file;
u32_le hash;
u32_le name_length;
};
-static_assert(sizeof(DirectoryEntry) == 0x14, "DirectoryEntry has incorrect size.");
+static_assert(sizeof(DirectoryEntry) == 0x18, "DirectoryEntry has incorrect size.");
struct FileEntry {
u32_le parent;
@@ -64,25 +65,22 @@ std::pair<Entry, std::string> GetEntry(const VirtualFile& file, std::size_t offs
return {entry, string};
}
-void ProcessFile(VirtualFile file, std::size_t file_offset, std::size_t data_offset,
- u32 this_file_offset, std::shared_ptr<VectorVfsDirectory> parent) {
- while (true) {
+void ProcessFile(const VirtualFile& file, std::size_t file_offset, std::size_t data_offset,
+ u32 this_file_offset, std::shared_ptr<VectorVfsDirectory>& parent) {
+ while (this_file_offset != ROMFS_ENTRY_EMPTY) {
auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset);
parent->AddFile(std::make_shared<OffsetVfsFile>(
file, entry.first.size, entry.first.offset + data_offset, entry.second));
- if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
- break;
-
this_file_offset = entry.first.sibling;
}
}
-void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file_offset,
+void ProcessDirectory(const VirtualFile& file, std::size_t dir_offset, std::size_t file_offset,
std::size_t data_offset, u32 this_dir_offset,
- std::shared_ptr<VectorVfsDirectory> parent) {
- while (true) {
+ std::shared_ptr<VectorVfsDirectory>& parent) {
+ while (this_dir_offset != ROMFS_ENTRY_EMPTY) {
auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset);
auto current = std::make_shared<VectorVfsDirectory>(
std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, entry.second);
@@ -97,14 +95,12 @@ void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file
}
parent->AddDirectory(current);
- if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
- break;
this_dir_offset = entry.first.sibling;
}
}
} // Anonymous namespace
-VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) {
+VirtualDir ExtractRomFS(VirtualFile file) {
RomFSHeader header{};
if (file->ReadObject(&header) != sizeof(RomFSHeader))
return nullptr;
@@ -113,27 +109,17 @@ VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) {
return nullptr;
const u64 file_offset = header.file_meta.offset;
- const u64 dir_offset = header.directory_meta.offset + 4;
-
- auto root =
- std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{}, std::vector<VirtualDir>{},
- file->GetName(), file->GetContainingDirectory());
-
- ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root);
+ const u64 dir_offset = header.directory_meta.offset;
- VirtualDir out = std::move(root);
+ auto root_container = std::make_shared<VectorVfsDirectory>();
- if (type == RomFSExtractionType::SingleDiscard)
- return out->GetSubdirectories().front();
+ ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root_container);
- while (out->GetSubdirectories().size() == 1 && out->GetFiles().empty()) {
- if (Common::ToLower(out->GetSubdirectories().front()->GetName()) == "data" &&
- type == RomFSExtractionType::Truncated)
- break;
- out = out->GetSubdirectories().front();
+ if (auto root = root_container->GetSubdirectory(""); root) {
+ return std::make_shared<CachedVfsDirectory>(std::move(root));
}
- return std::make_shared<CachedVfsDirectory>(std::move(out));
+ return nullptr;
}
VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) {
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h
index 5d7f0c2a8..b75ff1aad 100644
--- a/src/core/file_sys/romfs.h
+++ b/src/core/file_sys/romfs.h
@@ -7,16 +7,9 @@
namespace FileSys {
-enum class RomFSExtractionType {
- Full, // Includes data directory
- Truncated, // Traverses into data directory
- SingleDiscard, // Traverses into the first subdirectory of root
-};
-
// Converts a RomFS binary blob to VFS Filesystem
// Returns nullptr on failure
-VirtualDir ExtractRomFS(VirtualFile file,
- RomFSExtractionType type = RomFSExtractionType::Truncated);
+VirtualDir ExtractRomFS(VirtualFile file);
// Converts a VFS filesystem into a RomFS binary
// Returns nullptr on failure
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h
index 79114bb6d..fae15a556 100644
--- a/src/core/hid/emulated_console.h
+++ b/src/core/hid/emulated_console.h
@@ -38,14 +38,6 @@ using TouchParams = std::array<Common::ParamPackage, MaxTouchDevices>;
using ConsoleMotionValues = ConsoleMotionInfo;
using TouchValues = std::array<Common::Input::TouchStatus, MaxTouchDevices>;
-struct TouchFinger {
- u64 last_touch{};
- Common::Point<float> position{};
- u32 id{};
- TouchAttribute attribute{};
- bool pressed{};
-};
-
// Contains all motion related data that is used on the services
struct ConsoleMotion {
Common::Vec3f accel{};
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 2af3f06fc..a6e681e15 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -8,6 +8,7 @@
#include "common/thread.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/input_converter.h"
+#include "core/hle/service/hid/hid_util.h"
namespace Core::HID {
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
@@ -82,7 +83,7 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadStyleInde
}
void EmulatedController::ReloadFromSettings() {
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
+ const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
for (std::size_t index = 0; index < player.buttons.size(); ++index) {
@@ -96,18 +97,7 @@ void EmulatedController::ReloadFromSettings() {
}
controller.color_values = {};
- controller.colors_state.fullkey = {
- .body = GetNpadColor(player.body_color_left),
- .button = GetNpadColor(player.button_color_left),
- };
- controller.colors_state.left = {
- .body = GetNpadColor(player.body_color_left),
- .button = GetNpadColor(player.button_color_left),
- };
- controller.colors_state.right = {
- .body = GetNpadColor(player.body_color_right),
- .button = GetNpadColor(player.button_color_right),
- };
+ ReloadColorsFromSettings();
ring_params[0] = Common::ParamPackage(Settings::values.ringcon_analogs);
@@ -128,6 +118,30 @@ void EmulatedController::ReloadFromSettings() {
ReloadInput();
}
+void EmulatedController::ReloadColorsFromSettings() {
+ const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
+ const auto& player = Settings::values.players.GetValue()[player_index];
+
+ // Avoid updating colors if overridden by physical controller
+ if (controller.color_values[LeftIndex].body != 0 &&
+ controller.color_values[RightIndex].body != 0) {
+ return;
+ }
+
+ controller.colors_state.fullkey = {
+ .body = GetNpadColor(player.body_color_left),
+ .button = GetNpadColor(player.button_color_left),
+ };
+ controller.colors_state.left = {
+ .body = GetNpadColor(player.body_color_left),
+ .button = GetNpadColor(player.button_color_left),
+ };
+ controller.colors_state.right = {
+ .body = GetNpadColor(player.body_color_right),
+ .button = GetNpadColor(player.button_color_right),
+ };
+}
+
void EmulatedController::LoadDevices() {
// TODO(german77): Use more buttons to detect the correct device
const auto left_joycon = button_params[Settings::NativeButton::DRight];
@@ -202,7 +216,7 @@ void EmulatedController::LoadDevices() {
}
void EmulatedController::LoadTASParams() {
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
+ const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
Common::ParamPackage common_params{};
common_params.Set("engine", "tas");
common_params.Set("port", static_cast<int>(player_index));
@@ -230,10 +244,12 @@ void EmulatedController::LoadTASParams() {
tas_button_params[Settings::NativeButton::DUp].Set("button", 13);
tas_button_params[Settings::NativeButton::DRight].Set("button", 14);
tas_button_params[Settings::NativeButton::DDown].Set("button", 15);
- tas_button_params[Settings::NativeButton::SL].Set("button", 16);
- tas_button_params[Settings::NativeButton::SR].Set("button", 17);
+ tas_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
+ tas_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
tas_button_params[Settings::NativeButton::Home].Set("button", 18);
tas_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
+ tas_button_params[Settings::NativeButton::SLRight].Set("button", 20);
+ tas_button_params[Settings::NativeButton::SRRight].Set("button", 21);
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
@@ -249,7 +265,7 @@ void EmulatedController::LoadTASParams() {
}
void EmulatedController::LoadVirtualGamepadParams() {
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
+ const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
Common::ParamPackage common_params{};
common_params.Set("engine", "virtual_gamepad");
common_params.Set("port", static_cast<int>(player_index));
@@ -283,10 +299,12 @@ void EmulatedController::LoadVirtualGamepadParams() {
virtual_button_params[Settings::NativeButton::DUp].Set("button", 13);
virtual_button_params[Settings::NativeButton::DRight].Set("button", 14);
virtual_button_params[Settings::NativeButton::DDown].Set("button", 15);
- virtual_button_params[Settings::NativeButton::SL].Set("button", 16);
- virtual_button_params[Settings::NativeButton::SR].Set("button", 17);
+ virtual_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
+ virtual_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
virtual_button_params[Settings::NativeButton::Home].Set("button", 18);
virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
+ virtual_button_params[Settings::NativeButton::SLRight].Set("button", 20);
+ virtual_button_params[Settings::NativeButton::SRRight].Set("button", 21);
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
@@ -491,9 +509,11 @@ void EmulatedController::ReloadInput() {
});
}
turbo_button_state = 0;
+ is_initalized = true;
}
void EmulatedController::UnloadInput() {
+ is_initalized = false;
for (auto& button : button_devices) {
button.reset();
}
@@ -598,7 +618,7 @@ bool EmulatedController::IsConfiguring() const {
}
void EmulatedController::SaveCurrentConfig() {
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
+ const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
auto& player = Settings::values.players.GetValue()[player_index];
player.connected = is_connected;
player.controller_type = MapNPadToSettingsType(npad_type);
@@ -854,12 +874,16 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
controller.npad_button_state.down.Assign(current_status.value);
controller.debug_pad_button_state.d_down.Assign(current_status.value);
break;
- case Settings::NativeButton::SL:
+ case Settings::NativeButton::SLLeft:
controller.npad_button_state.left_sl.Assign(current_status.value);
+ break;
+ case Settings::NativeButton::SLRight:
controller.npad_button_state.right_sl.Assign(current_status.value);
break;
- case Settings::NativeButton::SR:
+ case Settings::NativeButton::SRLeft:
controller.npad_button_state.left_sr.Assign(current_status.value);
+ break;
+ case Settings::NativeButton::SRRight:
controller.npad_button_state.right_sr.Assign(current_status.value);
break;
case Settings::NativeButton::Home:
@@ -1091,30 +1115,30 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
bool is_charging = false;
bool is_powered = false;
- NpadBatteryLevel battery_level = 0;
+ NpadBatteryLevel battery_level = NpadBatteryLevel::Empty;
switch (controller.battery_values[index]) {
case Common::Input::BatteryLevel::Charging:
is_charging = true;
is_powered = true;
- battery_level = 6;
+ battery_level = NpadBatteryLevel::Full;
break;
case Common::Input::BatteryLevel::Medium:
- battery_level = 6;
+ battery_level = NpadBatteryLevel::High;
break;
case Common::Input::BatteryLevel::Low:
- battery_level = 4;
+ battery_level = NpadBatteryLevel::Low;
break;
case Common::Input::BatteryLevel::Critical:
- battery_level = 2;
+ battery_level = NpadBatteryLevel::Critical;
break;
case Common::Input::BatteryLevel::Empty:
- battery_level = 0;
+ battery_level = NpadBatteryLevel::Empty;
break;
case Common::Input::BatteryLevel::None:
case Common::Input::BatteryLevel::Full:
default:
is_powered = true;
- battery_level = 8;
+ battery_level = NpadBatteryLevel::Full;
break;
}
@@ -1185,13 +1209,16 @@ void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
}
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
+ if (!is_initalized) {
+ return false;
+ }
if (device_index >= output_devices.size()) {
return false;
}
if (!output_devices[device_index]) {
return false;
}
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
+ const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f;
@@ -1217,9 +1244,13 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
}
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
+ const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
+ if (!is_initalized) {
+ return false;
+ }
+
if (!player.vibration_enabled) {
return false;
}
@@ -1239,6 +1270,10 @@ Common::Input::DriverResult EmulatedController::SetPollingMode(
EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
+ if (!is_initalized) {
+ return Common::Input::DriverResult::InvalidHandle;
+ }
+
auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_output_device = output_devices[3];
@@ -1284,6 +1319,10 @@ bool EmulatedController::SetCameraFormat(
Core::IrSensor::ImageTransferProcessorFormat camera_format) {
LOG_INFO(Service_HID, "Set camera format {}", camera_format);
+ if (!is_initalized) {
+ return false;
+ }
+
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& camera_output_device = output_devices[2];
@@ -1307,6 +1346,11 @@ void EmulatedController::SetRingParam(Common::ParamPackage param) {
}
bool EmulatedController::HasNfc() const {
+
+ if (!is_initalized) {
+ return false;
+ }
+
const auto& nfc_output_device = output_devices[3];
switch (npad_type) {
@@ -1344,6 +1388,10 @@ bool EmulatedController::RemoveNfcHandle() {
}
bool EmulatedController::StartNfcPolling() {
+ if (!is_initalized) {
+ return false;
+ }
+
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3];
@@ -1355,6 +1403,10 @@ bool EmulatedController::StartNfcPolling() {
}
bool EmulatedController::StopNfcPolling() {
+ if (!is_initalized) {
+ return false;
+ }
+
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3];
@@ -1366,6 +1418,10 @@ bool EmulatedController::StopNfcPolling() {
}
bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {
+ if (!is_initalized) {
+ return false;
+ }
+
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3];
@@ -1378,6 +1434,10 @@ bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {
bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& request,
Common::Input::MifareRequest& out_data) {
+ if (!is_initalized) {
+ return false;
+ }
+
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3];
@@ -1390,6 +1450,10 @@ bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& requ
}
bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& request) {
+ if (!is_initalized) {
+ return false;
+ }
+
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3];
@@ -1401,6 +1465,10 @@ bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& req
}
bool EmulatedController::WriteNfc(const std::vector<u8>& data) {
+ if (!is_initalized) {
+ return false;
+ }
+
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3];
@@ -1412,6 +1480,10 @@ bool EmulatedController::WriteNfc(const std::vector<u8>& data) {
}
void EmulatedController::SetLedPattern() {
+ if (!is_initalized) {
+ return;
+ }
+
for (auto& device : output_devices) {
if (!device) {
continue;
@@ -1627,7 +1699,7 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
}
if (is_connected) {
LOG_WARNING(Service_HID, "Controller {} type changed while it's connected",
- NpadIdTypeToIndex(npad_id_type));
+ Service::HID::NpadIdTypeToIndex(npad_id_type));
}
npad_type = npad_type_;
}
@@ -1877,12 +1949,16 @@ NpadButton EmulatedController::GetTurboButtonMask() const {
case Settings::NativeButton::DDown:
button_mask.down.Assign(1);
break;
- case Settings::NativeButton::SL:
+ case Settings::NativeButton::SLLeft:
button_mask.left_sl.Assign(1);
+ break;
+ case Settings::NativeButton::SLRight:
button_mask.right_sl.Assign(1);
break;
- case Settings::NativeButton::SR:
+ case Settings::NativeButton::SRLeft:
button_mask.left_sr.Assign(1);
+ break;
+ case Settings::NativeButton::SRRight:
button_mask.right_sr.Assign(1);
break;
default:
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index d4500583e..d6e20ab66 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -253,6 +253,9 @@ public:
/// Overrides current mapped devices with the stored configuration and reloads all input devices
void ReloadFromSettings();
+ /// Updates current colors with the ones stored in the configuration
+ void ReloadColorsFromSettings();
+
/// Saves the current mapped configuration
void SaveCurrentConfig();
@@ -556,6 +559,7 @@ private:
NpadStyleTag supported_style_tag{NpadStyleSet::All};
bool is_connected{false};
bool is_configuring{false};
+ bool is_initalized{false};
bool system_buttons_enabled{true};
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
u32 turbo_button_state{0};
diff --git a/src/core/hid/hid_core.cpp b/src/core/hid/hid_core.cpp
index cf53c04d9..2cf25a870 100644
--- a/src/core/hid/hid_core.cpp
+++ b/src/core/hid/hid_core.cpp
@@ -6,6 +6,7 @@
#include "core/hid/emulated_controller.h"
#include "core/hid/emulated_devices.h"
#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/hid_util.h"
namespace Core::HID {
@@ -98,11 +99,11 @@ const EmulatedDevices* HIDCore::GetEmulatedDevices() const {
}
EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) {
- return GetEmulatedController(IndexToNpadIdType(index));
+ return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
}
const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) const {
- return GetEmulatedController(IndexToNpadIdType(index));
+ return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
}
void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) {
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 00beb40dd..4bf285f36 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -8,6 +8,7 @@
#include "common/common_types.h"
#include "common/point.h"
#include "common/uuid.h"
+#include "common/vector_math.h"
namespace Core::HID {
@@ -218,6 +219,13 @@ enum class NpadIdType : u32 {
Invalid = 0xFFFFFFFF,
};
+enum class NpadInterfaceType : u8 {
+ Bluetooth = 1,
+ Rail = 2,
+ Usb = 3,
+ Embedded = 4,
+};
+
// This is nn::hid::NpadStyleIndex
enum class NpadStyleIndex : u8 {
None = 0,
@@ -302,6 +310,15 @@ enum class TouchScreenModeForNx : u8 {
Heat2,
};
+// This is nn::hid::system::NpadBatteryLevel
+enum class NpadBatteryLevel : u32 {
+ Empty,
+ Critical,
+ Low,
+ High,
+ Full,
+};
+
// This is nn::hid::NpadStyleTag
struct NpadStyleTag {
union {
@@ -347,6 +364,14 @@ struct TouchState {
};
static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
+struct TouchFinger {
+ u64 last_touch{};
+ Common::Point<float> position{};
+ u32 id{};
+ TouchAttribute attribute{};
+ bool pressed{};
+};
+
// This is nn::hid::TouchScreenConfigurationForNx
struct TouchScreenConfigurationForNx {
TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting};
@@ -385,16 +410,12 @@ struct NpadGcTriggerState {
};
static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
-// This is nn::hid::system::NpadBatteryLevel
-using NpadBatteryLevel = u32;
-static_assert(sizeof(NpadBatteryLevel) == 0x4, "NpadBatteryLevel is an invalid size");
-
// This is nn::hid::system::NpadPowerInfo
struct NpadPowerInfo {
bool is_powered{};
bool is_charging{};
INSERT_PADDING_BYTES(0x6);
- NpadBatteryLevel battery_level{8};
+ NpadBatteryLevel battery_level{NpadBatteryLevel::Full};
};
static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
@@ -578,6 +599,29 @@ struct SixAxisSensorIcInformation {
static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
"SixAxisSensorIcInformation is an invalid size");
+// This is nn::hid::SixAxisSensorAttribute
+struct SixAxisSensorAttribute {
+ union {
+ u32 raw{};
+ BitField<0, 1, u32> is_connected;
+ BitField<1, 1, u32> is_interpolated;
+ };
+};
+static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
+
+// This is nn::hid::SixAxisSensorState
+struct SixAxisSensorState {
+ s64 delta_time{};
+ s64 sampling_number{};
+ Common::Vec3f accel{};
+ Common::Vec3f gyro{};
+ Common::Vec3f rotation{};
+ std::array<Common::Vec3f, 3> orientation{};
+ SixAxisSensorAttribute attribute{};
+ INSERT_PADDING_BYTES(4); // Reserved
+};
+static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
+
// This is nn::hid::VibrationDeviceHandle
struct VibrationDeviceHandle {
NpadStyleIndex npad_type{NpadStyleIndex::None};
@@ -688,60 +732,4 @@ struct UniquePadId {
};
static_assert(sizeof(UniquePadId) == 0x8, "UniquePadId is an invalid size");
-/// Converts a NpadIdType to an array index.
-constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
- switch (npad_id_type) {
- case NpadIdType::Player1:
- return 0;
- case NpadIdType::Player2:
- return 1;
- case NpadIdType::Player3:
- return 2;
- case NpadIdType::Player4:
- return 3;
- case NpadIdType::Player5:
- return 4;
- case NpadIdType::Player6:
- return 5;
- case NpadIdType::Player7:
- return 6;
- case NpadIdType::Player8:
- return 7;
- case NpadIdType::Handheld:
- return 8;
- case NpadIdType::Other:
- return 9;
- default:
- return 0;
- }
-}
-
-/// Converts an array index to a NpadIdType
-constexpr NpadIdType IndexToNpadIdType(size_t index) {
- switch (index) {
- case 0:
- return NpadIdType::Player1;
- case 1:
- return NpadIdType::Player2;
- case 2:
- return NpadIdType::Player3;
- case 3:
- return NpadIdType::Player4;
- case 4:
- return NpadIdType::Player5;
- case 5:
- return NpadIdType::Player6;
- case 6:
- return NpadIdType::Player7;
- case 7:
- return NpadIdType::Player8;
- case 8:
- return NpadIdType::Handheld;
- case 9:
- return NpadIdType::Other;
- default:
- return NpadIdType::Invalid;
- }
-}
-
} // namespace Core::HID
diff --git a/src/core/hid/input_interpreter.cpp b/src/core/hid/input_interpreter.cpp
index 76d6b8ab0..a6bdd28f2 100644
--- a/src/core/hid/input_interpreter.cpp
+++ b/src/core/hid/input_interpreter.cpp
@@ -5,21 +5,22 @@
#include "core/hid/hid_types.h"
#include "core/hid/input_interpreter.h"
#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/hid.h"
+#include "core/hle/service/hid/hid_server.h"
+#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/sm/sm.h"
InputInterpreter::InputInterpreter(Core::System& system)
: npad{system.ServiceManager()
- .GetService<Service::HID::Hid>("hid")
- ->GetAppletResource()
- ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {
+ .GetService<Service::HID::IHidServer>("hid")
+ ->GetResourceManager()
+ ->GetNpad()} {
ResetButtonStates();
}
InputInterpreter::~InputInterpreter() = default;
void InputInterpreter::PollInput() {
- const auto button_state = npad.GetAndResetPressState();
+ const auto button_state = npad->GetAndResetPressState();
previous_index = current_index;
current_index = (current_index + 1) % button_states.size();
diff --git a/src/core/hid/input_interpreter.h b/src/core/hid/input_interpreter.h
index 8c521b381..3569aac93 100644
--- a/src/core/hid/input_interpreter.h
+++ b/src/core/hid/input_interpreter.h
@@ -16,7 +16,7 @@ enum class NpadButton : u64;
}
namespace Service::HID {
-class Controller_NPad;
+class NPad;
}
/**
@@ -101,7 +101,7 @@ public:
}
private:
- Service::HID::Controller_NPad& npad;
+ std::shared_ptr<Service::HID::NPad> npad;
/// Stores 9 consecutive button states polled from HID.
std::array<Core::HID::NpadButton, 9> button_states{};
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
index 59364efa1..37fa39a73 100644
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
@@ -222,7 +222,7 @@ Result KSystemControl::AllocateSecureMemory(KernelCore& kernel, KVirtualAddress*
};
// We succeeded.
- *out = KPageTable::GetHeapVirtualAddress(kernel.MemoryLayout(), paddr);
+ *out = KPageTable::GetHeapVirtualAddress(kernel, paddr);
R_SUCCEED();
}
@@ -238,8 +238,17 @@ void KSystemControl::FreeSecureMemory(KernelCore& kernel, KVirtualAddress addres
ASSERT(Common::IsAligned(size, alignment));
// Close the secure region's pages.
- kernel.MemoryManager().Close(KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), address),
+ kernel.MemoryManager().Close(KPageTable::GetHeapPhysicalAddress(kernel, address),
size / PageSize);
}
+// Insecure Memory.
+KResourceLimit* KSystemControl::GetInsecureMemoryResourceLimit(KernelCore& kernel) {
+ return kernel.GetSystemResourceLimit();
+}
+
+u32 KSystemControl::GetInsecureMemoryPool() {
+ return static_cast<u32>(KMemoryManager::Pool::SystemNonSecure);
+}
+
} // namespace Kernel::Board::Nintendo::Nx
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
index ff1feec70..60c5e58b7 100644
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h
@@ -8,7 +8,8 @@
namespace Kernel {
class KernelCore;
-}
+class KResourceLimit;
+} // namespace Kernel
namespace Kernel::Board::Nintendo::Nx {
@@ -40,6 +41,10 @@ public:
u32 pool);
static void FreeSecureMemory(KernelCore& kernel, KVirtualAddress address, size_t size,
u32 pool);
+
+ // Insecure Memory.
+ static KResourceLimit* GetInsecureMemoryResourceLimit(KernelCore& kernel);
+ static u32 GetInsecureMemoryPool();
};
} // namespace Kernel::Board::Nintendo::Nx
diff --git a/src/core/hle/kernel/k_capabilities.cpp b/src/core/hle/kernel/k_capabilities.cpp
index e7da7a21d..274fee493 100644
--- a/src/core/hle/kernel/k_capabilities.cpp
+++ b/src/core/hle/kernel/k_capabilities.cpp
@@ -4,14 +4,16 @@
#include "core/hardware_properties.h"
#include "core/hle/kernel/k_capabilities.h"
#include "core/hle/kernel/k_memory_layout.h"
-#include "core/hle/kernel/k_page_table.h"
+#include "core/hle/kernel/k_process_page_table.h"
+#include "core/hle/kernel/k_trace.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/svc_version.h"
namespace Kernel {
-Result KCapabilities::InitializeForKip(std::span<const u32> kern_caps, KPageTable* page_table) {
+Result KCapabilities::InitializeForKip(std::span<const u32> kern_caps,
+ KProcessPageTable* page_table) {
// We're initializing an initial process.
m_svc_access_flags.reset();
m_irq_access_flags.reset();
@@ -41,7 +43,8 @@ Result KCapabilities::InitializeForKip(std::span<const u32> kern_caps, KPageTabl
R_RETURN(this->SetCapabilities(kern_caps, page_table));
}
-Result KCapabilities::InitializeForUser(std::span<const u32> user_caps, KPageTable* page_table) {
+Result KCapabilities::InitializeForUser(std::span<const u32> user_caps,
+ KProcessPageTable* page_table) {
// We're initializing a user process.
m_svc_access_flags.reset();
m_irq_access_flags.reset();
@@ -121,7 +124,7 @@ Result KCapabilities::SetSyscallMaskCapability(const u32 cap, u32& set_svc) {
R_SUCCEED();
}
-Result KCapabilities::MapRange_(const u32 cap, const u32 size_cap, KPageTable* page_table) {
+Result KCapabilities::MapRange_(const u32 cap, const u32 size_cap, KProcessPageTable* page_table) {
const auto range_pack = MapRange{cap};
const auto size_pack = MapRangeSize{size_cap};
@@ -142,16 +145,13 @@ Result KCapabilities::MapRange_(const u32 cap, const u32 size_cap, KPageTable* p
? KMemoryPermission::UserRead
: KMemoryPermission::UserReadWrite;
if (MapRangeSize{size_cap}.normal) {
- // R_RETURN(page_table->MapStatic(phys_addr, size, perm));
+ R_RETURN(page_table->MapStatic(phys_addr, size, perm));
} else {
- // R_RETURN(page_table->MapIo(phys_addr, size, perm));
+ R_RETURN(page_table->MapIo(phys_addr, size, perm));
}
-
- UNIMPLEMENTED();
- R_SUCCEED();
}
-Result KCapabilities::MapIoPage_(const u32 cap, KPageTable* page_table) {
+Result KCapabilities::MapIoPage_(const u32 cap, KProcessPageTable* page_table) {
// Get/validate address/size
const u64 phys_addr = MapIoPage{cap}.address.Value() * PageSize;
const size_t num_pages = 1;
@@ -160,10 +160,7 @@ Result KCapabilities::MapIoPage_(const u32 cap, KPageTable* page_table) {
R_UNLESS(((phys_addr + size - 1) & ~PhysicalMapAllowedMask) == 0, ResultInvalidAddress);
// Do the mapping.
- // R_RETURN(page_table->MapIo(phys_addr, size, KMemoryPermission_UserReadWrite));
-
- UNIMPLEMENTED();
- R_SUCCEED();
+ R_RETURN(page_table->MapIo(phys_addr, size, KMemoryPermission::UserReadWrite));
}
template <typename F>
@@ -200,13 +197,11 @@ Result KCapabilities::ProcessMapRegionCapability(const u32 cap, F f) {
R_SUCCEED();
}
-Result KCapabilities::MapRegion_(const u32 cap, KPageTable* page_table) {
+Result KCapabilities::MapRegion_(const u32 cap, KProcessPageTable* page_table) {
// Map each region into the process's page table.
return ProcessMapRegionCapability(
- cap, [](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
- // R_RETURN(page_table->MapRegion(region_type, perm));
- UNIMPLEMENTED();
- R_SUCCEED();
+ cap, [page_table](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
+ R_RETURN(page_table->MapRegion(region_type, perm));
});
}
@@ -280,7 +275,7 @@ Result KCapabilities::SetDebugFlagsCapability(const u32 cap) {
}
Result KCapabilities::SetCapability(const u32 cap, u32& set_flags, u32& set_svc,
- KPageTable* page_table) {
+ KProcessPageTable* page_table) {
// Validate this is a capability we can act on.
const auto type = GetCapabilityType(cap);
R_UNLESS(type != CapabilityType::Invalid, ResultInvalidArgument);
@@ -318,7 +313,7 @@ Result KCapabilities::SetCapability(const u32 cap, u32& set_flags, u32& set_svc,
}
}
-Result KCapabilities::SetCapabilities(std::span<const u32> caps, KPageTable* page_table) {
+Result KCapabilities::SetCapabilities(std::span<const u32> caps, KProcessPageTable* page_table) {
u32 set_flags = 0, set_svc = 0;
for (size_t i = 0; i < caps.size(); i++) {
@@ -335,6 +330,8 @@ Result KCapabilities::SetCapabilities(std::span<const u32> caps, KPageTable* pag
// Map the range.
R_TRY(this->MapRange_(cap, size_cap, page_table));
+ } else if (GetCapabilityType(cap) == CapabilityType::MapRegion && !IsKTraceEnabled) {
+ continue;
} else {
R_TRY(this->SetCapability(cap, set_flags, set_svc, page_table));
}
diff --git a/src/core/hle/kernel/k_capabilities.h b/src/core/hle/kernel/k_capabilities.h
index ebd4eedb1..013d952ad 100644
--- a/src/core/hle/kernel/k_capabilities.h
+++ b/src/core/hle/kernel/k_capabilities.h
@@ -15,15 +15,15 @@
namespace Kernel {
-class KPageTable;
+class KProcessPageTable;
class KernelCore;
class KCapabilities {
public:
constexpr explicit KCapabilities() = default;
- Result InitializeForKip(std::span<const u32> kern_caps, KPageTable* page_table);
- Result InitializeForUser(std::span<const u32> user_caps, KPageTable* page_table);
+ Result InitializeForKip(std::span<const u32> kern_caps, KProcessPageTable* page_table);
+ Result InitializeForUser(std::span<const u32> user_caps, KProcessPageTable* page_table);
static Result CheckCapabilities(KernelCore& kernel, std::span<const u32> user_caps);
@@ -264,9 +264,9 @@ private:
Result SetCorePriorityCapability(const u32 cap);
Result SetSyscallMaskCapability(const u32 cap, u32& set_svc);
- Result MapRange_(const u32 cap, const u32 size_cap, KPageTable* page_table);
- Result MapIoPage_(const u32 cap, KPageTable* page_table);
- Result MapRegion_(const u32 cap, KPageTable* page_table);
+ Result MapRange_(const u32 cap, const u32 size_cap, KProcessPageTable* page_table);
+ Result MapIoPage_(const u32 cap, KProcessPageTable* page_table);
+ Result MapRegion_(const u32 cap, KProcessPageTable* page_table);
Result SetInterruptPairCapability(const u32 cap);
Result SetProgramTypeCapability(const u32 cap);
Result SetKernelVersionCapability(const u32 cap);
@@ -277,8 +277,9 @@ private:
static Result ProcessMapRegionCapability(const u32 cap, F f);
static Result CheckMapRegion(KernelCore& kernel, const u32 cap);
- Result SetCapability(const u32 cap, u32& set_flags, u32& set_svc, KPageTable* page_table);
- Result SetCapabilities(std::span<const u32> caps, KPageTable* page_table);
+ Result SetCapability(const u32 cap, u32& set_flags, u32& set_svc,
+ KProcessPageTable* page_table);
+ Result SetCapabilities(std::span<const u32> caps, KProcessPageTable* page_table);
private:
Svc::SvcAccessFlagSet m_svc_access_flags{};
diff --git a/src/core/hle/kernel/k_device_address_space.cpp b/src/core/hle/kernel/k_device_address_space.cpp
index f48896715..f0703f795 100644
--- a/src/core/hle/kernel/k_device_address_space.cpp
+++ b/src/core/hle/kernel/k_device_address_space.cpp
@@ -54,7 +54,7 @@ Result KDeviceAddressSpace::Detach(Svc::DeviceName device_name) {
R_SUCCEED();
}
-Result KDeviceAddressSpace::Map(KPageTable* page_table, KProcessAddress process_address,
+Result KDeviceAddressSpace::Map(KProcessPageTable* page_table, KProcessAddress process_address,
size_t size, u64 device_address, u32 option, bool is_aligned) {
// Check that the address falls within the space.
R_UNLESS((m_space_address <= device_address &&
@@ -113,7 +113,7 @@ Result KDeviceAddressSpace::Map(KPageTable* page_table, KProcessAddress process_
R_SUCCEED();
}
-Result KDeviceAddressSpace::Unmap(KPageTable* page_table, KProcessAddress process_address,
+Result KDeviceAddressSpace::Unmap(KProcessPageTable* page_table, KProcessAddress process_address,
size_t size, u64 device_address) {
// Check that the address falls within the space.
R_UNLESS((m_space_address <= device_address &&
diff --git a/src/core/hle/kernel/k_device_address_space.h b/src/core/hle/kernel/k_device_address_space.h
index 18556e3cc..ff0ec8152 100644
--- a/src/core/hle/kernel/k_device_address_space.h
+++ b/src/core/hle/kernel/k_device_address_space.h
@@ -5,7 +5,7 @@
#include <string>
-#include "core/hle/kernel/k_page_table.h"
+#include "core/hle/kernel/k_process_page_table.h"
#include "core/hle/kernel/k_typed_address.h"
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/result.h"
@@ -31,23 +31,23 @@ public:
Result Attach(Svc::DeviceName device_name);
Result Detach(Svc::DeviceName device_name);
- Result MapByForce(KPageTable* page_table, KProcessAddress process_address, size_t size,
+ Result MapByForce(KProcessPageTable* page_table, KProcessAddress process_address, size_t size,
u64 device_address, u32 option) {
R_RETURN(this->Map(page_table, process_address, size, device_address, option, false));
}
- Result MapAligned(KPageTable* page_table, KProcessAddress process_address, size_t size,
+ Result MapAligned(KProcessPageTable* page_table, KProcessAddress process_address, size_t size,
u64 device_address, u32 option) {
R_RETURN(this->Map(page_table, process_address, size, device_address, option, true));
}
- Result Unmap(KPageTable* page_table, KProcessAddress process_address, size_t size,
+ Result Unmap(KProcessPageTable* page_table, KProcessAddress process_address, size_t size,
u64 device_address);
static void Initialize();
private:
- Result Map(KPageTable* page_table, KProcessAddress process_address, size_t size,
+ Result Map(KProcessPageTable* page_table, KProcessAddress process_address, size_t size,
u64 device_address, u32 option, bool is_aligned);
private:
diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h
index c8122644f..d7adb3169 100644
--- a/src/core/hle/kernel/k_memory_layout.h
+++ b/src/core/hle/kernel/k_memory_layout.h
@@ -394,6 +394,14 @@ private:
return region.GetEndAddress();
}
+public:
+ static const KMemoryRegion* Find(const KMemoryLayout& layout, KVirtualAddress address) {
+ return Find(address, layout.GetVirtualMemoryRegionTree());
+ }
+ static const KMemoryRegion* Find(const KMemoryLayout& layout, KPhysicalAddress address) {
+ return Find(address, layout.GetPhysicalMemoryRegionTree());
+ }
+
private:
u64 m_linear_phys_to_virt_diff{};
u64 m_linear_virt_to_phys_diff{};
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index cdc5572d8..0a973ec8c 100644
--- a/src/core/hle/kernel/k_memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -456,8 +456,7 @@ size_t KMemoryManager::Impl::Initialize(KPhysicalAddress address, size_t size,
}
void KMemoryManager::Impl::InitializeOptimizedMemory(KernelCore& kernel) {
- auto optimize_pa =
- KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
+ auto optimize_pa = KPageTable::GetHeapPhysicalAddress(kernel, m_management_region);
auto* optimize_map = kernel.System().DeviceMemory().GetPointer<u64>(optimize_pa);
std::memset(optimize_map, 0, CalculateOptimizedProcessOverheadSize(m_heap.GetSize()));
@@ -465,8 +464,7 @@ void KMemoryManager::Impl::InitializeOptimizedMemory(KernelCore& kernel) {
void KMemoryManager::Impl::TrackUnoptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
size_t num_pages) {
- auto optimize_pa =
- KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
+ auto optimize_pa = KPageTable::GetHeapPhysicalAddress(kernel, m_management_region);
auto* optimize_map = kernel.System().DeviceMemory().GetPointer<u64>(optimize_pa);
// Get the range we're tracking.
@@ -485,8 +483,7 @@ void KMemoryManager::Impl::TrackUnoptimizedAllocation(KernelCore& kernel, KPhysi
void KMemoryManager::Impl::TrackOptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
size_t num_pages) {
- auto optimize_pa =
- KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
+ auto optimize_pa = KPageTable::GetHeapPhysicalAddress(kernel, m_management_region);
auto* optimize_map = kernel.System().DeviceMemory().GetPointer<u64>(optimize_pa);
// Get the range we're tracking.
@@ -506,8 +503,7 @@ void KMemoryManager::Impl::TrackOptimizedAllocation(KernelCore& kernel, KPhysica
bool KMemoryManager::Impl::ProcessOptimizedAllocation(KernelCore& kernel, KPhysicalAddress block,
size_t num_pages, u8 fill_pattern) {
auto& device_memory = kernel.System().DeviceMemory();
- auto optimize_pa =
- KPageTable::GetHeapPhysicalAddress(kernel.MemoryLayout(), m_management_region);
+ auto optimize_pa = KPageTable::GetHeapPhysicalAddress(kernel, m_management_region);
auto* optimize_map = device_memory.GetPointer<u64>(optimize_pa);
// We want to return whether any pages were newly allocated.
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
deleted file mode 100644
index 1d47bdf6b..000000000
--- a/src/core/hle/kernel/k_page_table.cpp
+++ /dev/null
@@ -1,3519 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/alignment.h"
-#include "common/assert.h"
-#include "common/literals.h"
-#include "common/scope_exit.h"
-#include "common/settings.h"
-#include "core/core.h"
-#include "core/hle/kernel/k_address_space_info.h"
-#include "core/hle/kernel/k_memory_block.h"
-#include "core/hle/kernel/k_memory_block_manager.h"
-#include "core/hle/kernel/k_page_group.h"
-#include "core/hle/kernel/k_page_table.h"
-#include "core/hle/kernel/k_process.h"
-#include "core/hle/kernel/k_resource_limit.h"
-#include "core/hle/kernel/k_scoped_resource_reservation.h"
-#include "core/hle/kernel/k_system_control.h"
-#include "core/hle/kernel/k_system_resource.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/svc_results.h"
-#include "core/memory.h"
-
-namespace Kernel {
-
-namespace {
-
-class KScopedLightLockPair {
- YUZU_NON_COPYABLE(KScopedLightLockPair);
- YUZU_NON_MOVEABLE(KScopedLightLockPair);
-
-private:
- KLightLock* m_lower;
- KLightLock* m_upper;
-
-public:
- KScopedLightLockPair(KLightLock& lhs, KLightLock& rhs) {
- // Ensure our locks are in a consistent order.
- if (std::addressof(lhs) <= std::addressof(rhs)) {
- m_lower = std::addressof(lhs);
- m_upper = std::addressof(rhs);
- } else {
- m_lower = std::addressof(rhs);
- m_upper = std::addressof(lhs);
- }
-
- // Acquire both locks.
- m_lower->Lock();
- if (m_lower != m_upper) {
- m_upper->Lock();
- }
- }
-
- ~KScopedLightLockPair() {
- // Unlock the upper lock.
- if (m_upper != nullptr && m_upper != m_lower) {
- m_upper->Unlock();
- }
-
- // Unlock the lower lock.
- if (m_lower != nullptr) {
- m_lower->Unlock();
- }
- }
-
-public:
- // Utility.
- void TryUnlockHalf(KLightLock& lock) {
- // Only allow unlocking if the lock is half the pair.
- if (m_lower != m_upper) {
- // We want to be sure the lock is one we own.
- if (m_lower == std::addressof(lock)) {
- lock.Unlock();
- m_lower = nullptr;
- } else if (m_upper == std::addressof(lock)) {
- lock.Unlock();
- m_upper = nullptr;
- }
- }
- }
-};
-
-using namespace Common::Literals;
-
-constexpr size_t GetAddressSpaceWidthFromType(Svc::CreateProcessFlag as_type) {
- switch (as_type) {
- case Svc::CreateProcessFlag::AddressSpace32Bit:
- case Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias:
- return 32;
- case Svc::CreateProcessFlag::AddressSpace64BitDeprecated:
- return 36;
- case Svc::CreateProcessFlag::AddressSpace64Bit:
- return 39;
- default:
- ASSERT(false);
- return {};
- }
-}
-
-} // namespace
-
-KPageTable::KPageTable(Core::System& system_)
- : m_general_lock{system_.Kernel()},
- m_map_physical_memory_lock{system_.Kernel()}, m_system{system_}, m_kernel{system_.Kernel()} {}
-
-KPageTable::~KPageTable() = default;
-
-Result KPageTable::InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr,
- bool enable_das_merge, bool from_back,
- KMemoryManager::Pool pool, KProcessAddress code_addr,
- size_t code_size, KSystemResource* system_resource,
- KResourceLimit* resource_limit,
- Core::Memory::Memory& memory) {
-
- const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
- return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
- };
- const auto GetSpaceSize = [this](KAddressSpaceInfo::Type type) {
- return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type);
- };
-
- // Set the tracking memory
- m_memory = std::addressof(memory);
-
- // Set our width and heap/alias sizes
- m_address_space_width = GetAddressSpaceWidthFromType(as_type);
- const KProcessAddress start = 0;
- const KProcessAddress end{1ULL << m_address_space_width};
- size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)};
- size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)};
-
- ASSERT(code_addr < code_addr + code_size);
- ASSERT(code_addr + code_size - 1 <= end - 1);
-
- // Adjust heap/alias size if we don't have an alias region
- if (as_type == Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias) {
- heap_region_size += alias_region_size;
- alias_region_size = 0;
- }
-
- // Set code regions and determine remaining
- constexpr size_t RegionAlignment{2_MiB};
- KProcessAddress process_code_start{};
- KProcessAddress process_code_end{};
- size_t stack_region_size{};
- size_t kernel_map_region_size{};
-
- if (m_address_space_width == 39) {
- alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Alias);
- heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Heap);
- stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Stack);
- kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
- m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::Map39Bit);
- m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit);
- m_alias_code_region_start = m_code_region_start;
- m_alias_code_region_end = m_code_region_end;
- process_code_start = Common::AlignDown(GetInteger(code_addr), RegionAlignment);
- process_code_end = Common::AlignUp(GetInteger(code_addr) + code_size, RegionAlignment);
- } else {
- stack_region_size = 0;
- kernel_map_region_size = 0;
- m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::MapSmall);
- m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
- m_stack_region_start = m_code_region_start;
- m_alias_code_region_start = m_code_region_start;
- m_alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type::MapLarge) +
- GetSpaceSize(KAddressSpaceInfo::Type::MapLarge);
- m_stack_region_end = m_code_region_end;
- m_kernel_map_region_start = m_code_region_start;
- m_kernel_map_region_end = m_code_region_end;
- process_code_start = m_code_region_start;
- process_code_end = m_code_region_end;
- }
-
- // Set other basic fields
- m_enable_aslr = enable_aslr;
- m_enable_device_address_space_merge = enable_das_merge;
- m_address_space_start = start;
- m_address_space_end = end;
- m_is_kernel = false;
- m_memory_block_slab_manager = system_resource->GetMemoryBlockSlabManagerPointer();
- m_block_info_manager = system_resource->GetBlockInfoManagerPointer();
- m_resource_limit = resource_limit;
-
- // Determine the region we can place our undetermineds in
- KProcessAddress alloc_start{};
- size_t alloc_size{};
- if ((process_code_start - m_code_region_start) >= (end - process_code_end)) {
- alloc_start = m_code_region_start;
- alloc_size = process_code_start - m_code_region_start;
- } else {
- alloc_start = process_code_end;
- alloc_size = end - process_code_end;
- }
- const size_t needed_size =
- (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size);
- R_UNLESS(alloc_size >= needed_size, ResultOutOfMemory);
-
- const size_t remaining_size{alloc_size - needed_size};
-
- // Determine random placements for each region
- size_t alias_rnd{}, heap_rnd{}, stack_rnd{}, kmap_rnd{};
- if (enable_aslr) {
- alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
- RegionAlignment;
- heap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
- RegionAlignment;
- stack_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
- RegionAlignment;
- kmap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
- RegionAlignment;
- }
-
- // Setup heap and alias regions
- m_alias_region_start = alloc_start + alias_rnd;
- m_alias_region_end = m_alias_region_start + alias_region_size;
- m_heap_region_start = alloc_start + heap_rnd;
- m_heap_region_end = m_heap_region_start + heap_region_size;
-
- if (alias_rnd <= heap_rnd) {
- m_heap_region_start += alias_region_size;
- m_heap_region_end += alias_region_size;
- } else {
- m_alias_region_start += heap_region_size;
- m_alias_region_end += heap_region_size;
- }
-
- // Setup stack region
- if (stack_region_size) {
- m_stack_region_start = alloc_start + stack_rnd;
- m_stack_region_end = m_stack_region_start + stack_region_size;
-
- if (alias_rnd < stack_rnd) {
- m_stack_region_start += alias_region_size;
- m_stack_region_end += alias_region_size;
- } else {
- m_alias_region_start += stack_region_size;
- m_alias_region_end += stack_region_size;
- }
-
- if (heap_rnd < stack_rnd) {
- m_stack_region_start += heap_region_size;
- m_stack_region_end += heap_region_size;
- } else {
- m_heap_region_start += stack_region_size;
- m_heap_region_end += stack_region_size;
- }
- }
-
- // Setup kernel map region
- if (kernel_map_region_size) {
- m_kernel_map_region_start = alloc_start + kmap_rnd;
- m_kernel_map_region_end = m_kernel_map_region_start + kernel_map_region_size;
-
- if (alias_rnd < kmap_rnd) {
- m_kernel_map_region_start += alias_region_size;
- m_kernel_map_region_end += alias_region_size;
- } else {
- m_alias_region_start += kernel_map_region_size;
- m_alias_region_end += kernel_map_region_size;
- }
-
- if (heap_rnd < kmap_rnd) {
- m_kernel_map_region_start += heap_region_size;
- m_kernel_map_region_end += heap_region_size;
- } else {
- m_heap_region_start += kernel_map_region_size;
- m_heap_region_end += kernel_map_region_size;
- }
-
- if (stack_region_size) {
- if (stack_rnd < kmap_rnd) {
- m_kernel_map_region_start += stack_region_size;
- m_kernel_map_region_end += stack_region_size;
- } else {
- m_stack_region_start += kernel_map_region_size;
- m_stack_region_end += kernel_map_region_size;
- }
- }
- }
-
- // Set heap and fill members.
- m_current_heap_end = m_heap_region_start;
- m_max_heap_size = 0;
- m_mapped_physical_memory_size = 0;
- m_mapped_unsafe_physical_memory = 0;
- m_mapped_insecure_memory = 0;
- m_mapped_ipc_server_memory = 0;
-
- m_heap_fill_value = 0;
- m_ipc_fill_value = 0;
- m_stack_fill_value = 0;
-
- // Set allocation option.
- m_allocate_option =
- KMemoryManager::EncodeOption(pool, from_back ? KMemoryManager::Direction::FromBack
- : KMemoryManager::Direction::FromFront);
-
- // Ensure that we regions inside our address space
- auto IsInAddressSpace = [&](KProcessAddress addr) {
- return m_address_space_start <= addr && addr <= m_address_space_end;
- };
- ASSERT(IsInAddressSpace(m_alias_region_start));
- ASSERT(IsInAddressSpace(m_alias_region_end));
- ASSERT(IsInAddressSpace(m_heap_region_start));
- ASSERT(IsInAddressSpace(m_heap_region_end));
- ASSERT(IsInAddressSpace(m_stack_region_start));
- ASSERT(IsInAddressSpace(m_stack_region_end));
- ASSERT(IsInAddressSpace(m_kernel_map_region_start));
- ASSERT(IsInAddressSpace(m_kernel_map_region_end));
-
- // Ensure that we selected regions that don't overlap
- const KProcessAddress alias_start{m_alias_region_start};
- const KProcessAddress alias_last{m_alias_region_end - 1};
- const KProcessAddress heap_start{m_heap_region_start};
- const KProcessAddress heap_last{m_heap_region_end - 1};
- const KProcessAddress stack_start{m_stack_region_start};
- const KProcessAddress stack_last{m_stack_region_end - 1};
- const KProcessAddress kmap_start{m_kernel_map_region_start};
- const KProcessAddress kmap_last{m_kernel_map_region_end - 1};
- ASSERT(alias_last < heap_start || heap_last < alias_start);
- ASSERT(alias_last < stack_start || stack_last < alias_start);
- ASSERT(alias_last < kmap_start || kmap_last < alias_start);
- ASSERT(heap_last < stack_start || stack_last < heap_start);
- ASSERT(heap_last < kmap_start || kmap_last < heap_start);
-
- m_current_heap_end = m_heap_region_start;
- m_max_heap_size = 0;
- m_mapped_physical_memory_size = 0;
- m_memory_pool = pool;
-
- m_page_table_impl = std::make_unique<Common::PageTable>();
- m_page_table_impl->Resize(m_address_space_width, PageBits);
-
- // Initialize our memory block manager.
- R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end,
- m_memory_block_slab_manager));
-}
-
-void KPageTable::Finalize() {
- auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) {
- if (Settings::IsFastmemEnabled()) {
- m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size);
- }
- };
-
- // Finalize memory blocks.
- m_memory_block_manager.Finalize(m_memory_block_slab_manager, std::move(HostUnmapCallback));
-
- // Release any insecure mapped memory.
- if (m_mapped_insecure_memory) {
- UNIMPLEMENTED();
- }
-
- // Release any ipc server memory.
- if (m_mapped_ipc_server_memory) {
- UNIMPLEMENTED();
- }
-
- // Close the backing page table, as the destructor is not called for guest objects.
- m_page_table_impl.reset();
-}
-
-Result KPageTable::MapProcessCode(KProcessAddress addr, size_t num_pages, KMemoryState state,
- KMemoryPermission perm) {
- const u64 size{num_pages * PageSize};
-
- // Validate the mapping request.
- R_UNLESS(this->CanContain(addr, size, state), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Verify that the destination memory is unmapped.
- R_TRY(this->CheckMemoryState(addr, size, KMemoryState::All, KMemoryState::Free,
- KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::None, KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager);
-
- // Allocate and open.
- KPageGroup pg{m_kernel, m_block_info_manager};
- R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
- &pg, num_pages,
- KMemoryManager::EncodeOption(KMemoryManager::Pool::Application, m_allocation_option)));
-
- R_TRY(Operate(addr, num_pages, pg, OperationType::MapGroup));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
- KMemoryBlockDisableMergeAttribute::None);
-
- R_SUCCEED();
-}
-
-Result KPageTable::MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address,
- size_t size) {
- // Validate the mapping request.
- R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
- ResultInvalidMemoryRegion);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Verify that the source memory is normal heap.
- KMemoryState src_state{};
- KMemoryPermission src_perm{};
- size_t num_src_allocator_blocks{};
- R_TRY(this->CheckMemoryState(&src_state, &src_perm, nullptr, &num_src_allocator_blocks,
- src_address, size, KMemoryState::All, KMemoryState::Normal,
- KMemoryPermission::All, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::All, KMemoryAttribute::None));
-
- // Verify that the destination memory is unmapped.
- size_t num_dst_allocator_blocks{};
- R_TRY(this->CheckMemoryState(&num_dst_allocator_blocks, dst_address, size, KMemoryState::All,
- KMemoryState::Free, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryAttribute::None));
-
- // Create an update allocator for the source.
- Result src_allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
- m_memory_block_slab_manager,
- num_src_allocator_blocks);
- R_TRY(src_allocator_result);
-
- // Create an update allocator for the destination.
- Result dst_allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
- m_memory_block_slab_manager,
- num_dst_allocator_blocks);
- R_TRY(dst_allocator_result);
-
- // Map the code memory.
- {
- // Determine the number of pages being operated on.
- const size_t num_pages = size / PageSize;
-
- // Create page groups for the memory being mapped.
- KPageGroup pg{m_kernel, m_block_info_manager};
- AddRegionToPages(src_address, num_pages, pg);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Reprotect the source as kernel-read/not mapped.
- const auto new_perm = static_cast<KMemoryPermission>(KMemoryPermission::KernelRead |
- KMemoryPermission::NotMapped);
- R_TRY(Operate(src_address, num_pages, new_perm, OperationType::ChangePermissions));
-
- // Ensure that we unprotect the source pages on failure.
- auto unprot_guard = SCOPE_GUARD({
- ASSERT(this->Operate(src_address, num_pages, src_perm, OperationType::ChangePermissions)
- .IsSuccess());
- });
-
- // Map the alias pages.
- const KPageProperties dst_properties = {new_perm, false, false,
- DisableMergeAttribute::DisableHead};
- R_TRY(
- this->MapPageGroupImpl(updater.GetPageList(), dst_address, pg, dst_properties, false));
-
- // We successfully mapped the alias pages, so we don't need to unprotect the src pages on
- // failure.
- unprot_guard.Cancel();
-
- // Apply the memory block updates.
- m_memory_block_manager.Update(std::addressof(src_allocator), src_address, num_pages,
- src_state, new_perm, KMemoryAttribute::Locked,
- KMemoryBlockDisableMergeAttribute::Locked,
- KMemoryBlockDisableMergeAttribute::None);
- m_memory_block_manager.Update(std::addressof(dst_allocator), dst_address, num_pages,
- KMemoryState::AliasCode, new_perm, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::Normal,
- KMemoryBlockDisableMergeAttribute::None);
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address,
- size_t size,
- ICacheInvalidationStrategy icache_invalidation_strategy) {
- // Validate the mapping request.
- R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
- ResultInvalidMemoryRegion);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Verify that the source memory is locked normal heap.
- size_t num_src_allocator_blocks{};
- R_TRY(this->CheckMemoryState(std::addressof(num_src_allocator_blocks), src_address, size,
- KMemoryState::All, KMemoryState::Normal, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::Locked));
-
- // Verify that the destination memory is aliasable code.
- size_t num_dst_allocator_blocks{};
- R_TRY(this->CheckMemoryStateContiguous(
- std::addressof(num_dst_allocator_blocks), dst_address, size, KMemoryState::FlagCanCodeAlias,
- KMemoryState::FlagCanCodeAlias, KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::All & ~KMemoryAttribute::PermissionLocked, KMemoryAttribute::None));
-
- // Determine whether any pages being unmapped are code.
- bool any_code_pages = false;
- {
- KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(dst_address);
- while (true) {
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // Check if the memory has code flag.
- if ((info.GetState() & KMemoryState::FlagCode) != KMemoryState::None) {
- any_code_pages = true;
- break;
- }
-
- // Check if we're done.
- if (dst_address + size - 1 <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- ++it;
- }
- }
-
- // Ensure that we maintain the instruction cache.
- bool reprotected_pages = false;
- SCOPE_EXIT({
- if (reprotected_pages && any_code_pages) {
- if (icache_invalidation_strategy == ICacheInvalidationStrategy::InvalidateRange) {
- m_system.InvalidateCpuInstructionCacheRange(GetInteger(dst_address), size);
- } else {
- m_system.InvalidateCpuInstructionCaches();
- }
- }
- });
-
- // Unmap.
- {
- // Determine the number of pages being operated on.
- const size_t num_pages = size / PageSize;
-
- // Create an update allocator for the source.
- Result src_allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
- m_memory_block_slab_manager,
- num_src_allocator_blocks);
- R_TRY(src_allocator_result);
-
- // Create an update allocator for the destination.
- Result dst_allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
- m_memory_block_slab_manager,
- num_dst_allocator_blocks);
- R_TRY(dst_allocator_result);
-
- // Unmap the aliased copy of the pages.
- R_TRY(Operate(dst_address, num_pages, KMemoryPermission::None, OperationType::Unmap));
-
- // Try to set the permissions for the source pages back to what they should be.
- R_TRY(Operate(src_address, num_pages, KMemoryPermission::UserReadWrite,
- OperationType::ChangePermissions));
-
- // Apply the memory block updates.
- m_memory_block_manager.Update(
- std::addressof(dst_allocator), dst_address, num_pages, KMemoryState::None,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Normal);
- m_memory_block_manager.Update(
- std::addressof(src_allocator), src_address, num_pages, KMemoryState::Normal,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Locked);
-
- // Note that we reprotected pages.
- reprotected_pages = true;
- }
-
- R_SUCCEED();
-}
-
-KProcessAddress KPageTable::FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
- size_t num_pages, size_t alignment, size_t offset,
- size_t guard_pages) {
- KProcessAddress address = 0;
-
- if (num_pages <= region_num_pages) {
- if (this->IsAslrEnabled()) {
- UNIMPLEMENTED();
- }
- // Find the first free area.
- if (address == 0) {
- address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages,
- alignment, offset, guard_pages);
- }
- }
-
- return address;
-}
-
-Result KPageTable::MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages) {
- ASSERT(this->IsLockedByCurrentThread());
-
- const size_t size = num_pages * PageSize;
-
- // We're making a new group, not adding to an existing one.
- R_UNLESS(pg.empty(), ResultInvalidCurrentMemory);
-
- // Begin traversal.
- Common::PageTable::TraversalContext context;
- Common::PageTable::TraversalEntry next_entry;
- R_UNLESS(m_page_table_impl->BeginTraversal(next_entry, context, GetInteger(addr)),
- ResultInvalidCurrentMemory);
-
- // Prepare tracking variables.
- KPhysicalAddress cur_addr = next_entry.phys_addr;
- size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1));
- size_t tot_size = cur_size;
-
- // Iterate, adding to group as we go.
- const auto& memory_layout = m_system.Kernel().MemoryLayout();
- while (tot_size < size) {
- R_UNLESS(m_page_table_impl->ContinueTraversal(next_entry, context),
- ResultInvalidCurrentMemory);
-
- if (next_entry.phys_addr != (cur_addr + cur_size)) {
- const size_t cur_pages = cur_size / PageSize;
-
- R_UNLESS(IsHeapPhysicalAddress(memory_layout, cur_addr), ResultInvalidCurrentMemory);
- R_TRY(pg.AddBlock(cur_addr, cur_pages));
-
- cur_addr = next_entry.phys_addr;
- cur_size = next_entry.block_size;
- } else {
- cur_size += next_entry.block_size;
- }
-
- tot_size += next_entry.block_size;
- }
-
- // Ensure we add the right amount for the last block.
- if (tot_size > size) {
- cur_size -= (tot_size - size);
- }
-
- // Add the last block.
- const size_t cur_pages = cur_size / PageSize;
- R_UNLESS(IsHeapPhysicalAddress(memory_layout, cur_addr), ResultInvalidCurrentMemory);
- R_TRY(pg.AddBlock(cur_addr, cur_pages));
-
- R_SUCCEED();
-}
-
-bool KPageTable::IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr, size_t num_pages) {
- ASSERT(this->IsLockedByCurrentThread());
-
- const size_t size = num_pages * PageSize;
- const auto& memory_layout = m_system.Kernel().MemoryLayout();
-
- // Empty groups are necessarily invalid.
- if (pg.empty()) {
- return false;
- }
-
- // We're going to validate that the group we'd expect is the group we see.
- auto cur_it = pg.begin();
- KPhysicalAddress cur_block_address = cur_it->GetAddress();
- size_t cur_block_pages = cur_it->GetNumPages();
-
- auto UpdateCurrentIterator = [&]() {
- if (cur_block_pages == 0) {
- if ((++cur_it) == pg.end()) {
- return false;
- }
-
- cur_block_address = cur_it->GetAddress();
- cur_block_pages = cur_it->GetNumPages();
- }
- return true;
- };
-
- // Begin traversal.
- Common::PageTable::TraversalContext context;
- Common::PageTable::TraversalEntry next_entry;
- if (!m_page_table_impl->BeginTraversal(next_entry, context, GetInteger(addr))) {
- return false;
- }
-
- // Prepare tracking variables.
- KPhysicalAddress cur_addr = next_entry.phys_addr;
- size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1));
- size_t tot_size = cur_size;
-
- // Iterate, comparing expected to actual.
- while (tot_size < size) {
- if (!m_page_table_impl->ContinueTraversal(next_entry, context)) {
- return false;
- }
-
- if (next_entry.phys_addr != (cur_addr + cur_size)) {
- const size_t cur_pages = cur_size / PageSize;
-
- if (!IsHeapPhysicalAddress(memory_layout, cur_addr)) {
- return false;
- }
-
- if (!UpdateCurrentIterator()) {
- return false;
- }
-
- if (cur_block_address != cur_addr || cur_block_pages < cur_pages) {
- return false;
- }
-
- cur_block_address += cur_size;
- cur_block_pages -= cur_pages;
- cur_addr = next_entry.phys_addr;
- cur_size = next_entry.block_size;
- } else {
- cur_size += next_entry.block_size;
- }
-
- tot_size += next_entry.block_size;
- }
-
- // Ensure we compare the right amount for the last block.
- if (tot_size > size) {
- cur_size -= (tot_size - size);
- }
-
- if (!IsHeapPhysicalAddress(memory_layout, cur_addr)) {
- return false;
- }
-
- if (!UpdateCurrentIterator()) {
- return false;
- }
-
- return cur_block_address == cur_addr && cur_block_pages == (cur_size / PageSize);
-}
-
-Result KPageTable::UnmapProcessMemory(KProcessAddress dst_addr, size_t size,
- KPageTable& src_page_table, KProcessAddress src_addr) {
- // Acquire the table locks.
- KScopedLightLockPair lk(src_page_table.m_general_lock, m_general_lock);
-
- const size_t num_pages{size / PageSize};
-
- // Check that the memory is mapped in the destination process.
- size_t num_allocator_blocks;
- R_TRY(CheckMemoryState(&num_allocator_blocks, dst_addr, size, KMemoryState::All,
- KMemoryState::SharedCode, KMemoryPermission::UserReadWrite,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
- KMemoryAttribute::None));
-
- // Check that the memory is mapped in the source process.
- R_TRY(src_page_table.CheckMemoryState(src_addr, size, KMemoryState::FlagCanMapProcess,
- KMemoryState::FlagCanMapProcess, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- R_TRY(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap));
-
- // Apply the memory block update.
- m_memory_block_manager.Update(std::addressof(allocator), dst_addr, num_pages,
- KMemoryState::Free, KMemoryPermission::None,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::Normal);
-
- m_system.InvalidateCpuInstructionCaches();
-
- R_SUCCEED();
-}
-
-Result KPageTable::SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed,
- KProcessAddress address, size_t size,
- KMemoryPermission test_perm, KMemoryState dst_state) {
- // Validate pre-conditions.
- ASSERT(this->IsLockedByCurrentThread());
- ASSERT(test_perm == KMemoryPermission::UserReadWrite ||
- test_perm == KMemoryPermission::UserRead);
-
- // Check that the address is in range.
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Get the source permission.
- const auto src_perm = (test_perm == KMemoryPermission::UserReadWrite)
- ? KMemoryPermission::KernelReadWrite | KMemoryPermission::NotMapped
- : KMemoryPermission::UserRead;
-
- // Get aligned extents.
- const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(address), PageSize);
- const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(address) + size, PageSize);
- const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(address), PageSize);
- const KProcessAddress mapping_src_end = Common::AlignDown(GetInteger(address) + size, PageSize);
-
- const auto aligned_src_last = (aligned_src_end)-1;
- const auto mapping_src_last = (mapping_src_end)-1;
-
- // Get the test state and attribute mask.
- KMemoryState test_state;
- KMemoryAttribute test_attr_mask;
- switch (dst_state) {
- case KMemoryState::Ipc:
- test_state = KMemoryState::FlagCanUseIpc;
- test_attr_mask =
- KMemoryAttribute::Uncached | KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked;
- break;
- case KMemoryState::NonSecureIpc:
- test_state = KMemoryState::FlagCanUseNonSecureIpc;
- test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
- break;
- case KMemoryState::NonDeviceIpc:
- test_state = KMemoryState::FlagCanUseNonDeviceIpc;
- test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
- break;
- default:
- R_THROW(ResultInvalidCombination);
- }
-
- // Ensure that on failure, we roll back appropriately.
- size_t mapped_size = 0;
- ON_RESULT_FAILURE {
- if (mapped_size > 0) {
- this->CleanupForIpcClientOnServerSetupFailure(page_list, mapping_src_start, mapped_size,
- src_perm);
- }
- };
-
- size_t blocks_needed = 0;
-
- // Iterate, mapping as needed.
- KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(aligned_src_start);
- while (true) {
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // Validate the current block.
- R_TRY(this->CheckMemoryState(info, test_state, test_state, test_perm, test_perm,
- test_attr_mask, KMemoryAttribute::None));
-
- if (mapping_src_start < mapping_src_end && (mapping_src_start) < info.GetEndAddress() &&
- info.GetAddress() < GetInteger(mapping_src_end)) {
- const auto cur_start = info.GetAddress() >= GetInteger(mapping_src_start)
- ? info.GetAddress()
- : (mapping_src_start);
- const auto cur_end = mapping_src_last >= info.GetLastAddress() ? info.GetEndAddress()
- : (mapping_src_end);
- const size_t cur_size = cur_end - cur_start;
-
- if (info.GetAddress() < GetInteger(mapping_src_start)) {
- ++blocks_needed;
- }
- if (mapping_src_last < info.GetLastAddress()) {
- ++blocks_needed;
- }
-
- // Set the permissions on the block, if we need to.
- if ((info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != src_perm) {
- R_TRY(Operate(cur_start, cur_size / PageSize, src_perm,
- OperationType::ChangePermissions));
- }
-
- // Note that we mapped this part.
- mapped_size += cur_size;
- }
-
- // If the block is at the end, we're done.
- if (aligned_src_last <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- ++it;
- ASSERT(it != m_memory_block_manager.end());
- }
-
- if (out_blocks_needed != nullptr) {
- ASSERT(blocks_needed <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
- *out_blocks_needed = blocks_needed;
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::SetupForIpcServer(KProcessAddress* out_addr, size_t size,
- KProcessAddress src_addr, KMemoryPermission test_perm,
- KMemoryState dst_state, KPageTable& src_page_table,
- bool send) {
- ASSERT(this->IsLockedByCurrentThread());
- ASSERT(src_page_table.IsLockedByCurrentThread());
-
- // Check that we can theoretically map.
- const KProcessAddress region_start = m_alias_region_start;
- const size_t region_size = m_alias_region_end - m_alias_region_start;
- R_UNLESS(size < region_size, ResultOutOfAddressSpace);
-
- // Get aligned source extents.
- const KProcessAddress src_start = src_addr;
- const KProcessAddress src_end = src_addr + size;
- const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(src_start), PageSize);
- const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(src_start) + size, PageSize);
- const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(src_start), PageSize);
- const KProcessAddress mapping_src_end =
- Common::AlignDown(GetInteger(src_start) + size, PageSize);
- const size_t aligned_src_size = aligned_src_end - aligned_src_start;
- const size_t mapping_src_size =
- (mapping_src_start < mapping_src_end) ? (mapping_src_end - mapping_src_start) : 0;
-
- // Select a random address to map at.
- KProcessAddress dst_addr =
- this->FindFreeArea(region_start, region_size / PageSize, aligned_src_size / PageSize,
- PageSize, 0, this->GetNumGuardPages());
-
- R_UNLESS(dst_addr != 0, ResultOutOfAddressSpace);
-
- // Check that we can perform the operation we're about to perform.
- ASSERT(this->CanContain(dst_addr, aligned_src_size, dst_state));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Reserve space for any partial pages we allocate.
- const size_t unmapped_size = aligned_src_size - mapping_src_size;
- KScopedResourceReservation memory_reservation(
- m_resource_limit, LimitableResource::PhysicalMemoryMax, unmapped_size);
- R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
-
- // Ensure that we manage page references correctly.
- KPhysicalAddress start_partial_page = 0;
- KPhysicalAddress end_partial_page = 0;
- KProcessAddress cur_mapped_addr = dst_addr;
-
- // If the partial pages are mapped, an extra reference will have been opened. Otherwise, they'll
- // free on scope exit.
- SCOPE_EXIT({
- if (start_partial_page != 0) {
- m_system.Kernel().MemoryManager().Close(start_partial_page, 1);
- }
- if (end_partial_page != 0) {
- m_system.Kernel().MemoryManager().Close(end_partial_page, 1);
- }
- });
-
- ON_RESULT_FAILURE {
- if (cur_mapped_addr != dst_addr) {
- ASSERT(Operate(dst_addr, (cur_mapped_addr - dst_addr) / PageSize,
- KMemoryPermission::None, OperationType::Unmap)
- .IsSuccess());
- }
- };
-
- // Allocate the start page as needed.
- if (aligned_src_start < mapping_src_start) {
- start_partial_page =
- m_system.Kernel().MemoryManager().AllocateAndOpenContinuous(1, 1, m_allocate_option);
- R_UNLESS(start_partial_page != 0, ResultOutOfMemory);
- }
-
- // Allocate the end page as needed.
- if (mapping_src_end < aligned_src_end &&
- (aligned_src_start < mapping_src_end || aligned_src_start == mapping_src_start)) {
- end_partial_page =
- m_system.Kernel().MemoryManager().AllocateAndOpenContinuous(1, 1, m_allocate_option);
- R_UNLESS(end_partial_page != 0, ResultOutOfMemory);
- }
-
- // Get the implementation.
- auto& src_impl = src_page_table.PageTableImpl();
-
- // Get the fill value for partial pages.
- const auto fill_val = m_ipc_fill_value;
-
- // Begin traversal.
- Common::PageTable::TraversalContext context;
- Common::PageTable::TraversalEntry next_entry;
- bool traverse_valid =
- src_impl.BeginTraversal(next_entry, context, GetInteger(aligned_src_start));
- ASSERT(traverse_valid);
-
- // Prepare tracking variables.
- KPhysicalAddress cur_block_addr = next_entry.phys_addr;
- size_t cur_block_size =
- next_entry.block_size - ((cur_block_addr) & (next_entry.block_size - 1));
- size_t tot_block_size = cur_block_size;
-
- // Map the start page, if we have one.
- if (start_partial_page != 0) {
- // Ensure the page holds correct data.
- const KVirtualAddress start_partial_virt =
- GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), start_partial_page);
- if (send) {
- const size_t partial_offset = src_start - aligned_src_start;
- size_t copy_size, clear_size;
- if (src_end < mapping_src_start) {
- copy_size = size;
- clear_size = mapping_src_start - src_end;
- } else {
- copy_size = mapping_src_start - src_start;
- clear_size = 0;
- }
-
- std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val,
- partial_offset);
- std::memcpy(
- m_memory->GetPointer<void>(GetInteger(start_partial_virt) + partial_offset),
- m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress(
- m_system.Kernel().MemoryLayout(), cur_block_addr)) +
- partial_offset),
- copy_size);
- if (clear_size > 0) {
- std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt) +
- partial_offset + copy_size),
- fill_val, clear_size);
- }
- } else {
- std::memset(m_memory->GetPointer<void>(GetInteger(start_partial_virt)), fill_val,
- PageSize);
- }
-
- // Map the page.
- R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, start_partial_page));
-
- // Update tracking extents.
- cur_mapped_addr += PageSize;
- cur_block_addr += PageSize;
- cur_block_size -= PageSize;
-
- // If the block's size was one page, we may need to continue traversal.
- if (cur_block_size == 0 && aligned_src_size > PageSize) {
- traverse_valid = src_impl.ContinueTraversal(next_entry, context);
- ASSERT(traverse_valid);
-
- cur_block_addr = next_entry.phys_addr;
- cur_block_size = next_entry.block_size;
- tot_block_size += next_entry.block_size;
- }
- }
-
- // Map the remaining pages.
- while (aligned_src_start + tot_block_size < mapping_src_end) {
- // Continue the traversal.
- traverse_valid = src_impl.ContinueTraversal(next_entry, context);
- ASSERT(traverse_valid);
-
- // Process the block.
- if (next_entry.phys_addr != cur_block_addr + cur_block_size) {
- // Map the block we've been processing so far.
- R_TRY(Operate(cur_mapped_addr, cur_block_size / PageSize, test_perm, OperationType::Map,
- cur_block_addr));
-
- // Update tracking extents.
- cur_mapped_addr += cur_block_size;
- cur_block_addr = next_entry.phys_addr;
- cur_block_size = next_entry.block_size;
- } else {
- cur_block_size += next_entry.block_size;
- }
- tot_block_size += next_entry.block_size;
- }
-
- // Handle the last direct-mapped page.
- if (const KProcessAddress mapped_block_end =
- aligned_src_start + tot_block_size - cur_block_size;
- mapped_block_end < mapping_src_end) {
- const size_t last_block_size = mapping_src_end - mapped_block_end;
-
- // Map the last block.
- R_TRY(Operate(cur_mapped_addr, last_block_size / PageSize, test_perm, OperationType::Map,
- cur_block_addr));
-
- // Update tracking extents.
- cur_mapped_addr += last_block_size;
- cur_block_addr += last_block_size;
- if (mapped_block_end + cur_block_size < aligned_src_end &&
- cur_block_size == last_block_size) {
- traverse_valid = src_impl.ContinueTraversal(next_entry, context);
- ASSERT(traverse_valid);
-
- cur_block_addr = next_entry.phys_addr;
- }
- }
-
- // Map the end page, if we have one.
- if (end_partial_page != 0) {
- // Ensure the page holds correct data.
- const KVirtualAddress end_partial_virt =
- GetHeapVirtualAddress(m_system.Kernel().MemoryLayout(), end_partial_page);
- if (send) {
- const size_t copy_size = src_end - mapping_src_end;
- std::memcpy(m_memory->GetPointer<void>(GetInteger(end_partial_virt)),
- m_memory->GetPointer<void>(GetInteger(GetHeapVirtualAddress(
- m_system.Kernel().MemoryLayout(), cur_block_addr))),
- copy_size);
- std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt) + copy_size),
- fill_val, PageSize - copy_size);
- } else {
- std::memset(m_memory->GetPointer<void>(GetInteger(end_partial_virt)), fill_val,
- PageSize);
- }
-
- // Map the page.
- R_TRY(Operate(cur_mapped_addr, 1, test_perm, OperationType::Map, end_partial_page));
- }
-
- // Update memory blocks to reflect our changes
- m_memory_block_manager.Update(std::addressof(allocator), dst_addr, aligned_src_size / PageSize,
- dst_state, test_perm, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::Normal,
- KMemoryBlockDisableMergeAttribute::None);
-
- // Set the output address.
- *out_addr = dst_addr + (src_start - aligned_src_start);
-
- // We succeeded.
- memory_reservation.Commit();
- R_SUCCEED();
-}
-
-Result KPageTable::SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr,
- KPageTable& src_page_table, KMemoryPermission test_perm,
- KMemoryState dst_state, bool send) {
- // For convenience, alias this.
- KPageTable& dst_page_table = *this;
-
- // Acquire the table locks.
- KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(std::addressof(src_page_table));
-
- // Perform client setup.
- size_t num_allocator_blocks;
- R_TRY(src_page_table.SetupForIpcClient(updater.GetPageList(),
- std::addressof(num_allocator_blocks), src_addr, size,
- test_perm, dst_state));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- src_page_table.m_memory_block_slab_manager,
- num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Get the mapped extents.
- const KProcessAddress src_map_start = Common::AlignUp(GetInteger(src_addr), PageSize);
- const KProcessAddress src_map_end = Common::AlignDown(GetInteger(src_addr) + size, PageSize);
- const size_t src_map_size = src_map_end - src_map_start;
-
- // Ensure that we clean up appropriately if we fail after this.
- const auto src_perm = (test_perm == KMemoryPermission::UserReadWrite)
- ? KMemoryPermission::KernelReadWrite | KMemoryPermission::NotMapped
- : KMemoryPermission::UserRead;
- ON_RESULT_FAILURE {
- if (src_map_end > src_map_start) {
- src_page_table.CleanupForIpcClientOnServerSetupFailure(
- updater.GetPageList(), src_map_start, src_map_size, src_perm);
- }
- };
-
- // Perform server setup.
- R_TRY(dst_page_table.SetupForIpcServer(out_dst_addr, size, src_addr, test_perm, dst_state,
- src_page_table, send));
-
- // If anything was mapped, ipc-lock the pages.
- if (src_map_start < src_map_end) {
- // Get the source permission.
- src_page_table.m_memory_block_manager.UpdateLock(std::addressof(allocator), src_map_start,
- (src_map_end - src_map_start) / PageSize,
- &KMemoryBlock::LockForIpc, src_perm);
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::CleanupForIpcServer(KProcessAddress address, size_t size,
- KMemoryState dst_state) {
- // Validate the address.
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Validate the memory state.
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
- KMemoryState::All, dst_state, KMemoryPermission::UserRead,
- KMemoryPermission::UserRead, KMemoryAttribute::All,
- KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Get aligned extents.
- const KProcessAddress aligned_start = Common::AlignDown(GetInteger(address), PageSize);
- const KProcessAddress aligned_end = Common::AlignUp(GetInteger(address) + size, PageSize);
- const size_t aligned_size = aligned_end - aligned_start;
- const size_t aligned_num_pages = aligned_size / PageSize;
-
- // Unmap the pages.
- R_TRY(Operate(aligned_start, aligned_num_pages, KMemoryPermission::None, OperationType::Unmap));
-
- // Update memory blocks.
- m_memory_block_manager.Update(std::addressof(allocator), aligned_start, aligned_num_pages,
- KMemoryState::None, KMemoryPermission::None,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::Normal);
-
- // Release from the resource limit as relevant.
- const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize);
- const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize);
- const size_t mapping_size = (mapping_start < mapping_end) ? mapping_end - mapping_start : 0;
- m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, aligned_size - mapping_size);
-
- R_SUCCEED();
-}
-
-Result KPageTable::CleanupForIpcClient(KProcessAddress address, size_t size,
- KMemoryState dst_state) {
- // Validate the address.
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Get aligned source extents.
- const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize);
- const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize);
- const KProcessAddress mapping_last = mapping_end - 1;
- const size_t mapping_size = (mapping_start < mapping_end) ? (mapping_end - mapping_start) : 0;
-
- // If nothing was mapped, we're actually done immediately.
- R_SUCCEED_IF(mapping_size == 0);
-
- // Get the test state and attribute mask.
- KMemoryState test_state;
- KMemoryAttribute test_attr_mask;
- switch (dst_state) {
- case KMemoryState::Ipc:
- test_state = KMemoryState::FlagCanUseIpc;
- test_attr_mask =
- KMemoryAttribute::Uncached | KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked;
- break;
- case KMemoryState::NonSecureIpc:
- test_state = KMemoryState::FlagCanUseNonSecureIpc;
- test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
- break;
- case KMemoryState::NonDeviceIpc:
- test_state = KMemoryState::FlagCanUseNonDeviceIpc;
- test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
- break;
- default:
- R_THROW(ResultInvalidCombination);
- }
-
- // Lock the table.
- // NOTE: Nintendo does this *after* creating the updater below, but this does not follow
- // convention elsewhere in KPageTable.
- KScopedLightLock lk(m_general_lock);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Ensure that on failure, we roll back appropriately.
- size_t mapped_size = 0;
- ON_RESULT_FAILURE {
- if (mapped_size > 0) {
- // Determine where the mapping ends.
- const auto mapped_end = (mapping_start) + mapped_size;
- const auto mapped_last = mapped_end - 1;
-
- // Get current and next iterators.
- KMemoryBlockManager::const_iterator start_it =
- m_memory_block_manager.FindIterator(mapping_start);
- KMemoryBlockManager::const_iterator next_it = start_it;
- ++next_it;
-
- // Get the current block info.
- KMemoryInfo cur_info = start_it->GetMemoryInfo();
-
- // Create tracking variables.
- KProcessAddress cur_address = cur_info.GetAddress();
- size_t cur_size = cur_info.GetSize();
- bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission();
- bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1;
- bool first =
- cur_info.GetIpcDisableMergeCount() == 1 &&
- (cur_info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute::Locked) ==
- KMemoryBlockDisableMergeAttribute::None;
-
- while (((cur_address) + cur_size - 1) < mapped_last) {
- // Check that we have a next block.
- ASSERT(next_it != m_memory_block_manager.end());
-
- // Get the next info.
- const KMemoryInfo next_info = next_it->GetMemoryInfo();
-
- // Check if we can consolidate the next block's permission set with the current one.
-
- const bool next_perm_eq =
- next_info.GetPermission() == next_info.GetOriginalPermission();
- const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1;
- if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm &&
- cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) {
- // We can consolidate the reprotection for the current and next block into a
- // single call.
- cur_size += next_info.GetSize();
- } else {
- // We have to operate on the current block.
- if ((cur_needs_set_perm || first) && !cur_perm_eq) {
- ASSERT(Operate(cur_address, cur_size / PageSize, cur_info.GetPermission(),
- OperationType::ChangePermissions)
- .IsSuccess());
- }
-
- // Advance.
- cur_address = next_info.GetAddress();
- cur_size = next_info.GetSize();
- first = false;
- }
-
- // Advance.
- cur_info = next_info;
- cur_perm_eq = next_perm_eq;
- cur_needs_set_perm = next_needs_set_perm;
- ++next_it;
- }
-
- // Process the last block.
- if ((first || cur_needs_set_perm) && !cur_perm_eq) {
- ASSERT(Operate(cur_address, cur_size / PageSize, cur_info.GetPermission(),
- OperationType::ChangePermissions)
- .IsSuccess());
- }
- }
- };
-
- // Iterate, reprotecting as needed.
- {
- // Get current and next iterators.
- KMemoryBlockManager::const_iterator start_it =
- m_memory_block_manager.FindIterator(mapping_start);
- KMemoryBlockManager::const_iterator next_it = start_it;
- ++next_it;
-
- // Validate the current block.
- KMemoryInfo cur_info = start_it->GetMemoryInfo();
- ASSERT(this->CheckMemoryState(cur_info, test_state, test_state, KMemoryPermission::None,
- KMemoryPermission::None,
- test_attr_mask | KMemoryAttribute::IpcLocked,
- KMemoryAttribute::IpcLocked)
- .IsSuccess());
-
- // Create tracking variables.
- KProcessAddress cur_address = cur_info.GetAddress();
- size_t cur_size = cur_info.GetSize();
- bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission();
- bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1;
- bool first =
- cur_info.GetIpcDisableMergeCount() == 1 &&
- (cur_info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute::Locked) ==
- KMemoryBlockDisableMergeAttribute::None;
-
- while ((cur_address + cur_size - 1) < mapping_last) {
- // Check that we have a next block.
- ASSERT(next_it != m_memory_block_manager.end());
-
- // Get the next info.
- const KMemoryInfo next_info = next_it->GetMemoryInfo();
-
- // Validate the next block.
- ASSERT(this->CheckMemoryState(next_info, test_state, test_state,
- KMemoryPermission::None, KMemoryPermission::None,
- test_attr_mask | KMemoryAttribute::IpcLocked,
- KMemoryAttribute::IpcLocked)
- .IsSuccess());
-
- // Check if we can consolidate the next block's permission set with the current one.
- const bool next_perm_eq =
- next_info.GetPermission() == next_info.GetOriginalPermission();
- const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1;
- if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm &&
- cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) {
- // We can consolidate the reprotection for the current and next block into a single
- // call.
- cur_size += next_info.GetSize();
- } else {
- // We have to operate on the current block.
- if ((cur_needs_set_perm || first) && !cur_perm_eq) {
- R_TRY(Operate(cur_address, cur_size / PageSize,
- cur_needs_set_perm ? cur_info.GetOriginalPermission()
- : cur_info.GetPermission(),
- OperationType::ChangePermissions));
- }
-
- // Mark that we mapped the block.
- mapped_size += cur_size;
-
- // Advance.
- cur_address = next_info.GetAddress();
- cur_size = next_info.GetSize();
- first = false;
- }
-
- // Advance.
- cur_info = next_info;
- cur_perm_eq = next_perm_eq;
- cur_needs_set_perm = next_needs_set_perm;
- ++next_it;
- }
-
- // Process the last block.
- const auto lock_count =
- cur_info.GetIpcLockCount() +
- (next_it != m_memory_block_manager.end()
- ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount())
- : 0);
- if ((first || cur_needs_set_perm || (lock_count == 1)) && !cur_perm_eq) {
- R_TRY(Operate(cur_address, cur_size / PageSize,
- cur_needs_set_perm ? cur_info.GetOriginalPermission()
- : cur_info.GetPermission(),
- OperationType::ChangePermissions));
- }
- }
-
- // Create an update allocator.
- // NOTE: Guaranteed zero blocks needed here.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, 0);
- R_TRY(allocator_result);
-
- // Unlock the pages.
- m_memory_block_manager.UpdateLock(std::addressof(allocator), mapping_start,
- mapping_size / PageSize, &KMemoryBlock::UnlockForIpc,
- KMemoryPermission::None);
-
- R_SUCCEED();
-}
-
-void KPageTable::CleanupForIpcClientOnServerSetupFailure([[maybe_unused]] PageLinkedList* page_list,
- KProcessAddress address, size_t size,
- KMemoryPermission prot_perm) {
- ASSERT(this->IsLockedByCurrentThread());
- ASSERT(Common::IsAligned(GetInteger(address), PageSize));
- ASSERT(Common::IsAligned(size, PageSize));
-
- // Get the mapped extents.
- const KProcessAddress src_map_start = address;
- const KProcessAddress src_map_end = address + size;
- const KProcessAddress src_map_last = src_map_end - 1;
-
- // This function is only invoked when there's something to do.
- ASSERT(src_map_end > src_map_start);
-
- // Iterate over blocks, fixing permissions.
- KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address);
- while (true) {
- const KMemoryInfo info = it->GetMemoryInfo();
-
- const auto cur_start = info.GetAddress() >= GetInteger(src_map_start)
- ? info.GetAddress()
- : GetInteger(src_map_start);
- const auto cur_end =
- src_map_last <= info.GetLastAddress() ? src_map_end : info.GetEndAddress();
-
- // If we can, fix the protections on the block.
- if ((info.GetIpcLockCount() == 0 &&
- (info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm) ||
- (info.GetIpcLockCount() != 0 &&
- (info.GetOriginalPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm)) {
- // Check if we actually need to fix the protections on the block.
- if (cur_end == src_map_end || info.GetAddress() <= GetInteger(src_map_start) ||
- (info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm) {
- ASSERT(Operate(cur_start, (cur_end - cur_start) / PageSize, info.GetPermission(),
- OperationType::ChangePermissions)
- .IsSuccess());
- }
- }
-
- // If we're past the end of the region, we're done.
- if (src_map_last <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- ++it;
- ASSERT(it != m_memory_block_manager.end());
- }
-}
-
-Result KPageTable::MapPhysicalMemory(KProcessAddress address, size_t size) {
- // Lock the physical memory lock.
- KScopedLightLock phys_lk(m_map_physical_memory_lock);
-
- // Calculate the last address for convenience.
- const KProcessAddress last_address = address + size - 1;
-
- // Define iteration variables.
- KProcessAddress cur_address;
- size_t mapped_size;
-
- // The entire mapping process can be retried.
- while (true) {
- // Check if the memory is already mapped.
- {
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Iterate over the memory.
- cur_address = address;
- mapped_size = 0;
-
- auto it = m_memory_block_manager.FindIterator(cur_address);
- while (true) {
- // Check that the iterator is valid.
- ASSERT(it != m_memory_block_manager.end());
-
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // Check if we're done.
- if (last_address <= info.GetLastAddress()) {
- if (info.GetState() != KMemoryState::Free) {
- mapped_size += (last_address + 1 - cur_address);
- }
- break;
- }
-
- // Track the memory if it's mapped.
- if (info.GetState() != KMemoryState::Free) {
- mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address;
- }
-
- // Advance.
- cur_address = info.GetEndAddress();
- ++it;
- }
-
- // If the size mapped is the size requested, we've nothing to do.
- R_SUCCEED_IF(size == mapped_size);
- }
-
- // Allocate and map the memory.
- {
- // Reserve the memory from the process resource limit.
- KScopedResourceReservation memory_reservation(
- m_resource_limit, LimitableResource::PhysicalMemoryMax, size - mapped_size);
- R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
-
- // Allocate pages for the new memory.
- KPageGroup pg{m_kernel, m_block_info_manager};
- R_TRY(m_system.Kernel().MemoryManager().AllocateForProcess(
- &pg, (size - mapped_size) / PageSize, m_allocate_option, 0, 0));
-
- // If we fail in the next bit (or retry), we need to cleanup the pages.
- // auto pg_guard = SCOPE_GUARD {
- // pg.OpenFirst();
- // pg.Close();
- //};
-
- // Map the memory.
- {
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- size_t num_allocator_blocks = 0;
-
- // Verify that nobody has mapped memory since we first checked.
- {
- // Iterate over the memory.
- size_t checked_mapped_size = 0;
- cur_address = address;
-
- auto it = m_memory_block_manager.FindIterator(cur_address);
- while (true) {
- // Check that the iterator is valid.
- ASSERT(it != m_memory_block_manager.end());
-
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- const bool is_free = info.GetState() == KMemoryState::Free;
- if (is_free) {
- if (info.GetAddress() < GetInteger(address)) {
- ++num_allocator_blocks;
- }
- if (last_address < info.GetLastAddress()) {
- ++num_allocator_blocks;
- }
- }
-
- // Check if we're done.
- if (last_address <= info.GetLastAddress()) {
- if (!is_free) {
- checked_mapped_size += (last_address + 1 - cur_address);
- }
- break;
- }
-
- // Track the memory if it's mapped.
- if (!is_free) {
- checked_mapped_size +=
- KProcessAddress(info.GetEndAddress()) - cur_address;
- }
-
- // Advance.
- cur_address = info.GetEndAddress();
- ++it;
- }
-
- // If the size now isn't what it was before, somebody mapped or unmapped
- // concurrently. If this happened, retry.
- if (mapped_size != checked_mapped_size) {
- continue;
- }
- }
-
- // Create an update allocator.
- ASSERT(num_allocator_blocks <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager,
- num_allocator_blocks);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Prepare to iterate over the memory.
- auto pg_it = pg.begin();
- KPhysicalAddress pg_phys_addr = pg_it->GetAddress();
- size_t pg_pages = pg_it->GetNumPages();
-
- // Reset the current tracking address, and make sure we clean up on failure.
- // pg_guard.Cancel();
- cur_address = address;
- ON_RESULT_FAILURE {
- if (cur_address > address) {
- const KProcessAddress last_unmap_address = cur_address - 1;
-
- // Iterate, unmapping the pages.
- cur_address = address;
-
- auto it = m_memory_block_manager.FindIterator(cur_address);
- while (true) {
- // Check that the iterator is valid.
- ASSERT(it != m_memory_block_manager.end());
-
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // If the memory state is free, we mapped it and need to unmap it.
- if (info.GetState() == KMemoryState::Free) {
- // Determine the range to unmap.
- const size_t cur_pages =
- std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
- last_unmap_address + 1 - cur_address) /
- PageSize;
-
- // Unmap.
- ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None,
- OperationType::Unmap)
- .IsSuccess());
- }
-
- // Check if we're done.
- if (last_unmap_address <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- cur_address = info.GetEndAddress();
- ++it;
- }
- }
-
- // Release any remaining unmapped memory.
- m_system.Kernel().MemoryManager().OpenFirst(pg_phys_addr, pg_pages);
- m_system.Kernel().MemoryManager().Close(pg_phys_addr, pg_pages);
- for (++pg_it; pg_it != pg.end(); ++pg_it) {
- m_system.Kernel().MemoryManager().OpenFirst(pg_it->GetAddress(),
- pg_it->GetNumPages());
- m_system.Kernel().MemoryManager().Close(pg_it->GetAddress(),
- pg_it->GetNumPages());
- }
- };
-
- auto it = m_memory_block_manager.FindIterator(cur_address);
- while (true) {
- // Check that the iterator is valid.
- ASSERT(it != m_memory_block_manager.end());
-
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // If it's unmapped, we need to map it.
- if (info.GetState() == KMemoryState::Free) {
- // Determine the range to map.
- size_t map_pages =
- std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
- last_address + 1 - cur_address) /
- PageSize;
-
- // While we have pages to map, map them.
- {
- // Create a page group for the current mapping range.
- KPageGroup cur_pg(m_kernel, m_block_info_manager);
- {
- ON_RESULT_FAILURE_2 {
- cur_pg.OpenFirst();
- cur_pg.Close();
- };
-
- size_t remain_pages = map_pages;
- while (remain_pages > 0) {
- // Check if we're at the end of the physical block.
- if (pg_pages == 0) {
- // Ensure there are more pages to map.
- ASSERT(pg_it != pg.end());
-
- // Advance our physical block.
- ++pg_it;
- pg_phys_addr = pg_it->GetAddress();
- pg_pages = pg_it->GetNumPages();
- }
-
- // Add whatever we can to the current block.
- const size_t cur_pages = std::min(pg_pages, remain_pages);
- R_TRY(cur_pg.AddBlock(pg_phys_addr +
- ((pg_pages - cur_pages) * PageSize),
- cur_pages));
-
- // Advance.
- remain_pages -= cur_pages;
- pg_pages -= cur_pages;
- }
- }
-
- // Map the pages.
- R_TRY(this->Operate(cur_address, map_pages, cur_pg,
- OperationType::MapFirstGroup));
- }
- }
-
- // Check if we're done.
- if (last_address <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- cur_address = info.GetEndAddress();
- ++it;
- }
-
- // We succeeded, so commit the memory reservation.
- memory_reservation.Commit();
-
- // Increase our tracked mapped size.
- m_mapped_physical_memory_size += (size - mapped_size);
-
- // Update the relevant memory blocks.
- m_memory_block_manager.UpdateIfMatch(
- std::addressof(allocator), address, size / PageSize, KMemoryState::Free,
- KMemoryPermission::None, KMemoryAttribute::None, KMemoryState::Normal,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
- address == this->GetAliasRegionStart()
- ? KMemoryBlockDisableMergeAttribute::Normal
- : KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::None);
-
- R_SUCCEED();
- }
- }
- }
-}
-
-Result KPageTable::UnmapPhysicalMemory(KProcessAddress address, size_t size) {
- // Lock the physical memory lock.
- KScopedLightLock phys_lk(m_map_physical_memory_lock);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Calculate the last address for convenience.
- const KProcessAddress last_address = address + size - 1;
-
- // Define iteration variables.
- KProcessAddress map_start_address = 0;
- KProcessAddress map_last_address = 0;
-
- KProcessAddress cur_address;
- size_t mapped_size;
- size_t num_allocator_blocks = 0;
-
- // Check if the memory is mapped.
- {
- // Iterate over the memory.
- cur_address = address;
- mapped_size = 0;
-
- auto it = m_memory_block_manager.FindIterator(cur_address);
- while (true) {
- // Check that the iterator is valid.
- ASSERT(it != m_memory_block_manager.end());
-
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // Verify the memory's state.
- const bool is_normal = info.GetState() == KMemoryState::Normal &&
- info.GetAttribute() == KMemoryAttribute::None;
- const bool is_free = info.GetState() == KMemoryState::Free;
- R_UNLESS(is_normal || is_free, ResultInvalidCurrentMemory);
-
- if (is_normal) {
- R_UNLESS(info.GetAttribute() == KMemoryAttribute::None, ResultInvalidCurrentMemory);
-
- if (map_start_address == 0) {
- map_start_address = cur_address;
- }
- map_last_address =
- (last_address >= info.GetLastAddress()) ? info.GetLastAddress() : last_address;
-
- if (info.GetAddress() < GetInteger(address)) {
- ++num_allocator_blocks;
- }
- if (last_address < info.GetLastAddress()) {
- ++num_allocator_blocks;
- }
-
- mapped_size += (map_last_address + 1 - cur_address);
- }
-
- // Check if we're done.
- if (last_address <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- cur_address = info.GetEndAddress();
- ++it;
- }
-
- // If there's nothing mapped, we've nothing to do.
- R_SUCCEED_IF(mapped_size == 0);
- }
-
- // Create an update allocator.
- ASSERT(num_allocator_blocks <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Separate the mapping.
- R_TRY(Operate(map_start_address, (map_last_address + 1 - map_start_address) / PageSize,
- KMemoryPermission::None, OperationType::Separate));
-
- // Reset the current tracking address, and make sure we clean up on failure.
- cur_address = address;
-
- // Iterate over the memory, unmapping as we go.
- auto it = m_memory_block_manager.FindIterator(cur_address);
-
- const auto clear_merge_attr =
- (it->GetState() == KMemoryState::Normal &&
- it->GetAddress() == this->GetAliasRegionStart() && it->GetAddress() == address)
- ? KMemoryBlockDisableMergeAttribute::Normal
- : KMemoryBlockDisableMergeAttribute::None;
-
- while (true) {
- // Check that the iterator is valid.
- ASSERT(it != m_memory_block_manager.end());
-
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // If the memory state is normal, we need to unmap it.
- if (info.GetState() == KMemoryState::Normal) {
- // Determine the range to unmap.
- const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
- last_address + 1 - cur_address) /
- PageSize;
-
- // Unmap.
- ASSERT(Operate(cur_address, cur_pages, KMemoryPermission::None, OperationType::Unmap)
- .IsSuccess());
- }
-
- // Check if we're done.
- if (last_address <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- cur_address = info.GetEndAddress();
- ++it;
- }
-
- // Release the memory resource.
- m_mapped_physical_memory_size -= mapped_size;
- m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, mapped_size);
-
- // Update memory blocks.
- m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize,
- KMemoryState::Free, KMemoryPermission::None,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
- clear_merge_attr);
-
- // We succeeded.
- R_SUCCEED();
-}
-
-Result KPageTable::MapMemory(KProcessAddress dst_address, KProcessAddress src_address,
- size_t size) {
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Validate that the source address's state is valid.
- KMemoryState src_state;
- size_t num_src_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(src_state), nullptr, nullptr,
- std::addressof(num_src_allocator_blocks), src_address, size,
- KMemoryState::FlagCanAlias, KMemoryState::FlagCanAlias,
- KMemoryPermission::All, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::All, KMemoryAttribute::None));
-
- // Validate that the dst address's state is valid.
- size_t num_dst_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(num_dst_allocator_blocks), dst_address, size,
- KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryAttribute::None));
-
- // Create an update allocator for the source.
- Result src_allocator_result;
- KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
- m_memory_block_slab_manager,
- num_src_allocator_blocks);
- R_TRY(src_allocator_result);
-
- // Create an update allocator for the destination.
- Result dst_allocator_result;
- KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
- m_memory_block_slab_manager,
- num_dst_allocator_blocks);
- R_TRY(dst_allocator_result);
-
- // Map the memory.
- {
- // Determine the number of pages being operated on.
- const size_t num_pages = size / PageSize;
-
- // Create page groups for the memory being unmapped.
- KPageGroup pg{m_kernel, m_block_info_manager};
-
- // Create the page group representing the source.
- R_TRY(this->MakePageGroup(pg, src_address, num_pages));
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Reprotect the source as kernel-read/not mapped.
- const KMemoryPermission new_src_perm = static_cast<KMemoryPermission>(
- KMemoryPermission::KernelRead | KMemoryPermission::NotMapped);
- const KMemoryAttribute new_src_attr = KMemoryAttribute::Locked;
- const KPageProperties src_properties = {new_src_perm, false, false,
- DisableMergeAttribute::DisableHeadBodyTail};
- R_TRY(this->Operate(src_address, num_pages, src_properties.perm,
- OperationType::ChangePermissions));
-
- // Ensure that we unprotect the source pages on failure.
- ON_RESULT_FAILURE {
- const KPageProperties unprotect_properties = {
- KMemoryPermission::UserReadWrite, false, false,
- DisableMergeAttribute::EnableHeadBodyTail};
- ASSERT(this->Operate(src_address, num_pages, unprotect_properties.perm,
- OperationType::ChangePermissions) == ResultSuccess);
- };
-
- // Map the alias pages.
- const KPageProperties dst_map_properties = {KMemoryPermission::UserReadWrite, false, false,
- DisableMergeAttribute::DisableHead};
- R_TRY(this->MapPageGroupImpl(updater.GetPageList(), dst_address, pg, dst_map_properties,
- false));
-
- // Apply the memory block updates.
- m_memory_block_manager.Update(std::addressof(src_allocator), src_address, num_pages,
- src_state, new_src_perm, new_src_attr,
- KMemoryBlockDisableMergeAttribute::Locked,
- KMemoryBlockDisableMergeAttribute::None);
- m_memory_block_manager.Update(
- std::addressof(dst_allocator), dst_address, num_pages, KMemoryState::Stack,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::Normal, KMemoryBlockDisableMergeAttribute::None);
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::UnmapMemory(KProcessAddress dst_address, KProcessAddress src_address,
- size_t size) {
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Validate that the source address's state is valid.
- KMemoryState src_state;
- size_t num_src_allocator_blocks;
- R_TRY(this->CheckMemoryState(
- std::addressof(src_state), nullptr, nullptr, std::addressof(num_src_allocator_blocks),
- src_address, size, KMemoryState::FlagCanAlias, KMemoryState::FlagCanAlias,
- KMemoryPermission::All, KMemoryPermission::NotMapped | KMemoryPermission::KernelRead,
- KMemoryAttribute::All, KMemoryAttribute::Locked));
-
- // Validate that the dst address's state is valid.
- KMemoryPermission dst_perm;
- size_t num_dst_allocator_blocks;
- R_TRY(this->CheckMemoryState(
- nullptr, std::addressof(dst_perm), nullptr, std::addressof(num_dst_allocator_blocks),
- dst_address, size, KMemoryState::All, KMemoryState::Stack, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::None));
-
- // Create an update allocator for the source.
- Result src_allocator_result;
- KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
- m_memory_block_slab_manager,
- num_src_allocator_blocks);
- R_TRY(src_allocator_result);
-
- // Create an update allocator for the destination.
- Result dst_allocator_result;
- KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
- m_memory_block_slab_manager,
- num_dst_allocator_blocks);
- R_TRY(dst_allocator_result);
-
- // Unmap the memory.
- {
- // Determine the number of pages being operated on.
- const size_t num_pages = size / PageSize;
-
- // Create page groups for the memory being unmapped.
- KPageGroup pg{m_kernel, m_block_info_manager};
-
- // Create the page group representing the destination.
- R_TRY(this->MakePageGroup(pg, dst_address, num_pages));
-
- // Ensure the page group is the valid for the source.
- R_UNLESS(this->IsValidPageGroup(pg, src_address, num_pages), ResultInvalidMemoryRegion);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Unmap the aliased copy of the pages.
- const KPageProperties dst_unmap_properties = {KMemoryPermission::None, false, false,
- DisableMergeAttribute::None};
- R_TRY(
- this->Operate(dst_address, num_pages, dst_unmap_properties.perm, OperationType::Unmap));
-
- // Ensure that we re-map the aliased pages on failure.
- ON_RESULT_FAILURE {
- this->RemapPageGroup(updater.GetPageList(), dst_address, size, pg);
- };
-
- // Try to set the permissions for the source pages back to what they should be.
- const KPageProperties src_properties = {KMemoryPermission::UserReadWrite, false, false,
- DisableMergeAttribute::EnableAndMergeHeadBodyTail};
- R_TRY(this->Operate(src_address, num_pages, src_properties.perm,
- OperationType::ChangePermissions));
-
- // Apply the memory block updates.
- m_memory_block_manager.Update(
- std::addressof(src_allocator), src_address, num_pages, src_state,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Locked);
- m_memory_block_manager.Update(
- std::addressof(dst_allocator), dst_address, num_pages, KMemoryState::None,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Normal);
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::AllocateAndMapPagesImpl(PageLinkedList* page_list, KProcessAddress address,
- size_t num_pages, KMemoryPermission perm) {
- ASSERT(this->IsLockedByCurrentThread());
-
- // Create a page group to hold the pages we allocate.
- KPageGroup pg{m_kernel, m_block_info_manager};
-
- // Allocate the pages.
- R_TRY(
- m_kernel.MemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, m_allocate_option));
-
- // Ensure that the page group is closed when we're done working with it.
- SCOPE_EXIT({ pg.Close(); });
-
- // Clear all pages.
- for (const auto& it : pg) {
- std::memset(m_system.DeviceMemory().GetPointer<void>(it.GetAddress()), m_heap_fill_value,
- it.GetSize());
- }
-
- // Map the pages.
- R_RETURN(this->Operate(address, num_pages, pg, OperationType::MapGroup));
-}
-
-Result KPageTable::MapPageGroupImpl(PageLinkedList* page_list, KProcessAddress address,
- const KPageGroup& pg, const KPageProperties properties,
- bool reuse_ll) {
- ASSERT(this->IsLockedByCurrentThread());
-
- // Note the current address, so that we can iterate.
- const KProcessAddress start_address = address;
- KProcessAddress cur_address = address;
-
- // Ensure that we clean up on failure.
- ON_RESULT_FAILURE {
- ASSERT(!reuse_ll);
- if (cur_address != start_address) {
- const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
- DisableMergeAttribute::None};
- ASSERT(this->Operate(start_address, (cur_address - start_address) / PageSize,
- unmap_properties.perm, OperationType::Unmap) == ResultSuccess);
- }
- };
-
- // Iterate, mapping all pages in the group.
- for (const auto& block : pg) {
- // Map and advance.
- const KPageProperties cur_properties =
- (cur_address == start_address)
- ? properties
- : KPageProperties{properties.perm, properties.io, properties.uncached,
- DisableMergeAttribute::None};
- this->Operate(cur_address, block.GetNumPages(), cur_properties.perm, OperationType::Map,
- block.GetAddress());
- cur_address += block.GetSize();
- }
-
- // We succeeded!
- R_SUCCEED();
-}
-
-void KPageTable::RemapPageGroup(PageLinkedList* page_list, KProcessAddress address, size_t size,
- const KPageGroup& pg) {
- ASSERT(this->IsLockedByCurrentThread());
-
- // Note the current address, so that we can iterate.
- const KProcessAddress start_address = address;
- const KProcessAddress last_address = start_address + size - 1;
- const KProcessAddress end_address = last_address + 1;
-
- // Iterate over the memory.
- auto pg_it = pg.begin();
- ASSERT(pg_it != pg.end());
-
- KPhysicalAddress pg_phys_addr = pg_it->GetAddress();
- size_t pg_pages = pg_it->GetNumPages();
-
- auto it = m_memory_block_manager.FindIterator(start_address);
- while (true) {
- // Check that the iterator is valid.
- ASSERT(it != m_memory_block_manager.end());
-
- // Get the memory info.
- const KMemoryInfo info = it->GetMemoryInfo();
-
- // Determine the range to map.
- KProcessAddress map_address = std::max<KProcessAddress>(info.GetAddress(), start_address);
- const KProcessAddress map_end_address =
- std::min<KProcessAddress>(info.GetEndAddress(), end_address);
- ASSERT(map_end_address != map_address);
-
- // Determine if we should disable head merge.
- const bool disable_head_merge =
- info.GetAddress() >= GetInteger(start_address) &&
- True(info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute::Normal);
- const KPageProperties map_properties = {
- info.GetPermission(), false, false,
- disable_head_merge ? DisableMergeAttribute::DisableHead : DisableMergeAttribute::None};
-
- // While we have pages to map, map them.
- size_t map_pages = (map_end_address - map_address) / PageSize;
- while (map_pages > 0) {
- // Check if we're at the end of the physical block.
- if (pg_pages == 0) {
- // Ensure there are more pages to map.
- ASSERT(pg_it != pg.end());
-
- // Advance our physical block.
- ++pg_it;
- pg_phys_addr = pg_it->GetAddress();
- pg_pages = pg_it->GetNumPages();
- }
-
- // Map whatever we can.
- const size_t cur_pages = std::min(pg_pages, map_pages);
- ASSERT(this->Operate(map_address, map_pages, map_properties.perm, OperationType::Map,
- pg_phys_addr) == ResultSuccess);
-
- // Advance.
- map_address += cur_pages * PageSize;
- map_pages -= cur_pages;
-
- pg_phys_addr += cur_pages * PageSize;
- pg_pages -= cur_pages;
- }
-
- // Check if we're done.
- if (last_address <= info.GetLastAddress()) {
- break;
- }
-
- // Advance.
- ++it;
- }
-
- // Check that we re-mapped precisely the page group.
- ASSERT((++pg_it) == pg.end());
-}
-
-Result KPageTable::MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
- KPhysicalAddress phys_addr, bool is_pa_valid,
- KProcessAddress region_start, size_t region_num_pages,
- KMemoryState state, KMemoryPermission perm) {
- ASSERT(Common::IsAligned(alignment, PageSize) && alignment >= PageSize);
-
- // Ensure this is a valid map request.
- R_UNLESS(this->CanContain(region_start, region_num_pages * PageSize, state),
- ResultInvalidCurrentMemory);
- R_UNLESS(num_pages < region_num_pages, ResultOutOfMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Find a random address to map at.
- KProcessAddress addr = this->FindFreeArea(region_start, region_num_pages, num_pages, alignment,
- 0, this->GetNumGuardPages());
- R_UNLESS(addr != 0, ResultOutOfMemory);
- ASSERT(Common::IsAligned(GetInteger(addr), alignment));
- ASSERT(this->CanContain(addr, num_pages * PageSize, state));
- ASSERT(this->CheckMemoryState(addr, num_pages * PageSize, KMemoryState::All, KMemoryState::Free,
- KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::None, KMemoryAttribute::None) == ResultSuccess);
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Perform mapping operation.
- if (is_pa_valid) {
- const KPageProperties properties = {perm, false, false, DisableMergeAttribute::DisableHead};
- R_TRY(this->Operate(addr, num_pages, properties.perm, OperationType::Map, phys_addr));
- } else {
- R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), addr, num_pages, perm));
- }
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
- KMemoryBlockDisableMergeAttribute::None);
-
- // We successfully mapped the pages.
- *out_addr = addr;
- R_SUCCEED();
-}
-
-Result KPageTable::MapPages(KProcessAddress address, size_t num_pages, KMemoryState state,
- KMemoryPermission perm) {
- // Check that the map is in range.
- const size_t size = num_pages * PageSize;
- R_UNLESS(this->CanContain(address, size, state), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check the memory state.
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
- KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Map the pages.
- R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), address, num_pages, perm));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, state, perm,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
- KMemoryBlockDisableMergeAttribute::None);
-
- R_SUCCEED();
-}
-
-Result KPageTable::UnmapPages(KProcessAddress address, size_t num_pages, KMemoryState state) {
- // Check that the unmap is in range.
- const size_t size = num_pages * PageSize;
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check the memory state.
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
- KMemoryState::All, state, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Perform the unmap.
- const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
- DisableMergeAttribute::None};
- R_TRY(this->Operate(address, num_pages, unmap_properties.perm, OperationType::Unmap));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState::Free,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::Normal);
-
- R_SUCCEED();
-}
-
-Result KPageTable::MapPageGroup(KProcessAddress* out_addr, const KPageGroup& pg,
- KProcessAddress region_start, size_t region_num_pages,
- KMemoryState state, KMemoryPermission perm) {
- ASSERT(!this->IsLockedByCurrentThread());
-
- // Ensure this is a valid map request.
- const size_t num_pages = pg.GetNumPages();
- R_UNLESS(this->CanContain(region_start, region_num_pages * PageSize, state),
- ResultInvalidCurrentMemory);
- R_UNLESS(num_pages < region_num_pages, ResultOutOfMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Find a random address to map at.
- KProcessAddress addr = this->FindFreeArea(region_start, region_num_pages, num_pages, PageSize,
- 0, this->GetNumGuardPages());
- R_UNLESS(addr != 0, ResultOutOfMemory);
- ASSERT(this->CanContain(addr, num_pages * PageSize, state));
- ASSERT(this->CheckMemoryState(addr, num_pages * PageSize, KMemoryState::All, KMemoryState::Free,
- KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::None, KMemoryAttribute::None) == ResultSuccess);
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Perform mapping operation.
- const KPageProperties properties = {perm, false, false, DisableMergeAttribute::DisableHead};
- R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
- KMemoryBlockDisableMergeAttribute::None);
-
- // We successfully mapped the pages.
- *out_addr = addr;
- R_SUCCEED();
-}
-
-Result KPageTable::MapPageGroup(KProcessAddress addr, const KPageGroup& pg, KMemoryState state,
- KMemoryPermission perm) {
- ASSERT(!this->IsLockedByCurrentThread());
-
- // Ensure this is a valid map request.
- const size_t num_pages = pg.GetNumPages();
- const size_t size = num_pages * PageSize;
- R_UNLESS(this->CanContain(addr, size, state), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check if state allows us to map.
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), addr, size,
- KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Perform mapping operation.
- const KPageProperties properties = {perm, false, false, DisableMergeAttribute::DisableHead};
- R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
- KMemoryBlockDisableMergeAttribute::None);
-
- // We successfully mapped the pages.
- R_SUCCEED();
-}
-
-Result KPageTable::UnmapPageGroup(KProcessAddress address, const KPageGroup& pg,
- KMemoryState state) {
- ASSERT(!this->IsLockedByCurrentThread());
-
- // Ensure this is a valid unmap request.
- const size_t num_pages = pg.GetNumPages();
- const size_t size = num_pages * PageSize;
- R_UNLESS(this->CanContain(address, size, state), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check if state allows us to unmap.
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
- KMemoryState::All, state, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::None));
-
- // Check that the page group is valid.
- R_UNLESS(this->IsValidPageGroup(pg, address, num_pages), ResultInvalidCurrentMemory);
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // We're going to perform an update, so create a helper.
- KScopedPageTableUpdater updater(this);
-
- // Perform unmapping operation.
- const KPageProperties properties = {KMemoryPermission::None, false, false,
- DisableMergeAttribute::None};
- R_TRY(this->Operate(address, num_pages, properties.perm, OperationType::Unmap));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState::Free,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::Normal);
-
- R_SUCCEED();
-}
-
-Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages,
- KMemoryState state_mask, KMemoryState state,
- KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr) {
- // Ensure that the page group isn't null.
- ASSERT(out != nullptr);
-
- // Make sure that the region we're mapping is valid for the table.
- const size_t size = num_pages * PageSize;
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check if state allows us to create the group.
- R_TRY(this->CheckMemoryState(address, size, state_mask | KMemoryState::FlagReferenceCounted,
- state | KMemoryState::FlagReferenceCounted, perm_mask, perm,
- attr_mask, attr));
-
- // Create a new page group for the region.
- R_TRY(this->MakePageGroup(*out, address, num_pages));
-
- R_SUCCEED();
-}
-
-Result KPageTable::SetProcessMemoryPermission(KProcessAddress addr, size_t size,
- Svc::MemoryPermission svc_perm) {
- const size_t num_pages = size / PageSize;
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Verify we can change the memory permission.
- KMemoryState old_state;
- KMemoryPermission old_perm;
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), nullptr,
- std::addressof(num_allocator_blocks), addr, size,
- KMemoryState::FlagCode, KMemoryState::FlagCode,
- KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::All, KMemoryAttribute::None));
-
- // Determine new perm/state.
- const KMemoryPermission new_perm = ConvertToKMemoryPermission(svc_perm);
- KMemoryState new_state = old_state;
- const bool is_w = (new_perm & KMemoryPermission::UserWrite) == KMemoryPermission::UserWrite;
- const bool is_x = (new_perm & KMemoryPermission::UserExecute) == KMemoryPermission::UserExecute;
- const bool was_x =
- (old_perm & KMemoryPermission::UserExecute) == KMemoryPermission::UserExecute;
- ASSERT(!(is_w && is_x));
-
- if (is_w) {
- switch (old_state) {
- case KMemoryState::Code:
- new_state = KMemoryState::CodeData;
- break;
- case KMemoryState::AliasCode:
- new_state = KMemoryState::AliasCodeData;
- break;
- default:
- ASSERT(false);
- break;
- }
- }
-
- // Succeed if there's nothing to do.
- R_SUCCEED_IF(old_perm == new_perm && old_state == new_state);
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Perform mapping operation.
- const auto operation =
- was_x ? OperationType::ChangePermissionsAndRefresh : OperationType::ChangePermissions;
- R_TRY(Operate(addr, num_pages, new_perm, operation));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::None);
-
- // Ensure cache coherency, if we're setting pages as executable.
- if (is_x) {
- m_system.InvalidateCpuInstructionCacheRange(GetInteger(addr), size);
- }
-
- R_SUCCEED();
-}
-
-KMemoryInfo KPageTable::QueryInfoImpl(KProcessAddress addr) {
- KScopedLightLock lk(m_general_lock);
-
- return m_memory_block_manager.FindBlock(addr)->GetMemoryInfo();
-}
-
-KMemoryInfo KPageTable::QueryInfo(KProcessAddress addr) {
- if (!Contains(addr, 1)) {
- return {
- .m_address = GetInteger(m_address_space_end),
- .m_size = 0 - GetInteger(m_address_space_end),
- .m_state = static_cast<KMemoryState>(Svc::MemoryState::Inaccessible),
- .m_device_disable_merge_left_count = 0,
- .m_device_disable_merge_right_count = 0,
- .m_ipc_lock_count = 0,
- .m_device_use_count = 0,
- .m_ipc_disable_merge_count = 0,
- .m_permission = KMemoryPermission::None,
- .m_attribute = KMemoryAttribute::None,
- .m_original_permission = KMemoryPermission::None,
- .m_disable_merge_attribute = KMemoryBlockDisableMergeAttribute::None,
- };
- }
-
- return QueryInfoImpl(addr);
-}
-
-Result KPageTable::SetMemoryPermission(KProcessAddress addr, size_t size,
- Svc::MemoryPermission svc_perm) {
- const size_t num_pages = size / PageSize;
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Verify we can change the memory permission.
- KMemoryState old_state;
- KMemoryPermission old_perm;
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), nullptr,
- std::addressof(num_allocator_blocks), addr, size,
- KMemoryState::FlagCanReprotect, KMemoryState::FlagCanReprotect,
- KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::All, KMemoryAttribute::None));
-
- // Determine new perm.
- const KMemoryPermission new_perm = ConvertToKMemoryPermission(svc_perm);
- R_SUCCEED_IF(old_perm == new_perm);
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Perform mapping operation.
- R_TRY(Operate(addr, num_pages, new_perm, OperationType::ChangePermissions));
-
- // Update the blocks.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
- KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::None);
-
- R_SUCCEED();
-}
-
-Result KPageTable::SetMemoryAttribute(KProcessAddress addr, size_t size, u32 mask, u32 attr) {
- const size_t num_pages = size / PageSize;
- ASSERT((static_cast<KMemoryAttribute>(mask) | KMemoryAttribute::SetMask) ==
- KMemoryAttribute::SetMask);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Verify we can change the memory attribute.
- KMemoryState old_state;
- KMemoryPermission old_perm;
- KMemoryAttribute old_attr;
- size_t num_allocator_blocks;
- constexpr auto AttributeTestMask =
- ~(KMemoryAttribute::SetMask | KMemoryAttribute::DeviceShared);
- const KMemoryState state_test_mask =
- static_cast<KMemoryState>(((mask & static_cast<u32>(KMemoryAttribute::Uncached))
- ? static_cast<u32>(KMemoryState::FlagCanChangeAttribute)
- : 0) |
- ((mask & static_cast<u32>(KMemoryAttribute::PermissionLocked))
- ? static_cast<u32>(KMemoryState::FlagCanPermissionLock)
- : 0));
- R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm),
- std::addressof(old_attr), std::addressof(num_allocator_blocks),
- addr, size, state_test_mask, state_test_mask,
- KMemoryPermission::None, KMemoryPermission::None,
- AttributeTestMask, KMemoryAttribute::None, ~AttributeTestMask));
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // If we need to, perform a change attribute operation.
- if (True(KMemoryAttribute::Uncached & static_cast<KMemoryAttribute>(mask))) {
- // Perform operation.
- R_TRY(this->Operate(addr, num_pages, old_perm,
- OperationType::ChangePermissionsAndRefreshAndFlush, 0));
- }
-
- // Update the blocks.
- m_memory_block_manager.UpdateAttribute(std::addressof(allocator), addr, num_pages,
- static_cast<KMemoryAttribute>(mask),
- static_cast<KMemoryAttribute>(attr));
-
- R_SUCCEED();
-}
-
-Result KPageTable::SetMaxHeapSize(size_t size) {
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Only process page tables are allowed to set heap size.
- ASSERT(!this->IsKernel());
-
- m_max_heap_size = size;
-
- R_SUCCEED();
-}
-
-Result KPageTable::SetHeapSize(u64* out, size_t size) {
- // Lock the physical memory mutex.
- KScopedLightLock map_phys_mem_lk(m_map_physical_memory_lock);
-
- // Try to perform a reduction in heap, instead of an extension.
- KProcessAddress cur_address{};
- size_t allocation_size{};
- {
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Validate that setting heap size is possible at all.
- R_UNLESS(!m_is_kernel, ResultOutOfMemory);
- R_UNLESS(size <= static_cast<size_t>(m_heap_region_end - m_heap_region_start),
- ResultOutOfMemory);
- R_UNLESS(size <= m_max_heap_size, ResultOutOfMemory);
-
- if (size < GetHeapSize()) {
- // The size being requested is less than the current size, so we need to free the end of
- // the heap.
-
- // Validate memory state.
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks),
- m_heap_region_start + size, GetHeapSize() - size,
- KMemoryState::All, KMemoryState::Normal,
- KMemoryPermission::All, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::All, KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager,
- num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Unmap the end of the heap.
- const auto num_pages = (GetHeapSize() - size) / PageSize;
- R_TRY(Operate(m_heap_region_start + size, num_pages, KMemoryPermission::None,
- OperationType::Unmap));
-
- // Release the memory from the resource limit.
- m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, num_pages * PageSize);
-
- // Apply the memory block update.
- m_memory_block_manager.Update(std::addressof(allocator), m_heap_region_start + size,
- num_pages, KMemoryState::Free, KMemoryPermission::None,
- KMemoryAttribute::None,
- KMemoryBlockDisableMergeAttribute::None,
- size == 0 ? KMemoryBlockDisableMergeAttribute::Normal
- : KMemoryBlockDisableMergeAttribute::None);
-
- // Update the current heap end.
- m_current_heap_end = m_heap_region_start + size;
-
- // Set the output.
- *out = GetInteger(m_heap_region_start);
- R_SUCCEED();
- } else if (size == GetHeapSize()) {
- // The size requested is exactly the current size.
- *out = GetInteger(m_heap_region_start);
- R_SUCCEED();
- } else {
- // We have to allocate memory. Determine how much to allocate and where while the table
- // is locked.
- cur_address = m_current_heap_end;
- allocation_size = size - GetHeapSize();
- }
- }
-
- // Reserve memory for the heap extension.
- KScopedResourceReservation memory_reservation(
- m_resource_limit, LimitableResource::PhysicalMemoryMax, allocation_size);
- R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
-
- // Allocate pages for the heap extension.
- KPageGroup pg{m_kernel, m_block_info_manager};
- R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
- &pg, allocation_size / PageSize,
- KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option)));
-
- // Clear all the newly allocated pages.
- for (const auto& it : pg) {
- std::memset(m_system.DeviceMemory().GetPointer<void>(it.GetAddress()), m_heap_fill_value,
- it.GetSize());
- }
-
- // Map the pages.
- {
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Ensure that the heap hasn't changed since we began executing.
- ASSERT(cur_address == m_current_heap_end);
-
- // Check the memory state.
- size_t num_allocator_blocks{};
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), m_current_heap_end,
- allocation_size, KMemoryState::All, KMemoryState::Free,
- KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::None, KMemoryAttribute::None));
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(
- std::addressof(allocator_result), m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Map the pages.
- const auto num_pages = allocation_size / PageSize;
- R_TRY(Operate(m_current_heap_end, num_pages, pg, OperationType::MapGroup));
-
- // Clear all the newly allocated pages.
- for (size_t cur_page = 0; cur_page < num_pages; ++cur_page) {
- std::memset(m_memory->GetPointer(m_current_heap_end + (cur_page * PageSize)), 0,
- PageSize);
- }
-
- // We succeeded, so commit our memory reservation.
- memory_reservation.Commit();
-
- // Apply the memory block update.
- m_memory_block_manager.Update(
- std::addressof(allocator), m_current_heap_end, num_pages, KMemoryState::Normal,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
- m_heap_region_start == m_current_heap_end ? KMemoryBlockDisableMergeAttribute::Normal
- : KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::None);
-
- // Update the current heap end.
- m_current_heap_end = m_heap_region_start + size;
-
- // Set the output.
- *out = GetInteger(m_heap_region_start);
- R_SUCCEED();
- }
-}
-
-Result KPageTable::LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address,
- size_t size, KMemoryPermission perm,
- bool is_aligned, bool check_heap) {
- // Lightly validate the range before doing anything else.
- const size_t num_pages = size / PageSize;
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check the memory state.
- const auto test_state =
- (is_aligned ? KMemoryState::FlagCanAlignedDeviceMap : KMemoryState::FlagCanDeviceMap) |
- (check_heap ? KMemoryState::FlagReferenceCounted : KMemoryState::None);
- size_t num_allocator_blocks;
- KMemoryState old_state;
- R_TRY(this->CheckMemoryState(std::addressof(old_state), nullptr, nullptr,
- std::addressof(num_allocator_blocks), address, size, test_state,
- test_state, perm, perm,
- KMemoryAttribute::IpcLocked | KMemoryAttribute::Locked,
- KMemoryAttribute::None, KMemoryAttribute::DeviceShared));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Update the memory blocks.
- m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages,
- &KMemoryBlock::ShareToDevice, KMemoryPermission::None);
-
- // Set whether the locked memory was io.
- *out_is_io =
- static_cast<Svc::MemoryState>(old_state & KMemoryState::Mask) == Svc::MemoryState::Io;
-
- R_SUCCEED();
-}
-
-Result KPageTable::LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size,
- bool check_heap) {
- // Lightly validate the range before doing anything else.
- const size_t num_pages = size / PageSize;
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check the memory state.
- const auto test_state = KMemoryState::FlagCanDeviceMap |
- (check_heap ? KMemoryState::FlagReferenceCounted : KMemoryState::None);
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryStateContiguous(
- std::addressof(num_allocator_blocks), address, size, test_state, test_state,
- KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
-
- // Create an update allocator.
- Result allocator_result;
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Update the memory blocks.
- const KMemoryBlockManager::MemoryBlockLockFunction lock_func =
- m_enable_device_address_space_merge
- ? &KMemoryBlock::UpdateDeviceDisableMergeStateForShare
- : &KMemoryBlock::UpdateDeviceDisableMergeStateForShareRight;
- m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages, lock_func,
- KMemoryPermission::None);
-
- R_SUCCEED();
-}
-
-Result KPageTable::UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) {
- // Lightly validate the range before doing anything else.
- const size_t num_pages = size / PageSize;
- R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check the memory state.
- size_t num_allocator_blocks;
- R_TRY(this->CheckMemoryStateContiguous(
- std::addressof(num_allocator_blocks), address, size, KMemoryState::FlagCanDeviceMap,
- KMemoryState::FlagCanDeviceMap, KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Update the memory blocks.
- m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages,
- &KMemoryBlock::UnshareToDevice, KMemoryPermission::None);
-
- R_SUCCEED();
-}
-
-Result KPageTable::LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address,
- size_t size) {
- R_RETURN(this->LockMemoryAndOpen(
- nullptr, out, address, size, KMemoryState::FlagCanIpcUserBuffer,
- KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::All,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None,
- KMemoryPermission::NotMapped | KMemoryPermission::KernelReadWrite,
- KMemoryAttribute::Locked));
-}
-
-Result KPageTable::UnlockForIpcUserBuffer(KProcessAddress address, size_t size) {
- R_RETURN(this->UnlockMemory(address, size, KMemoryState::FlagCanIpcUserBuffer,
- KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::Locked, nullptr));
-}
-
-Result KPageTable::LockForTransferMemory(KPageGroup* out, KProcessAddress address, size_t size,
- KMemoryPermission perm) {
- R_RETURN(this->LockMemoryAndOpen(out, nullptr, address, size, KMemoryState::FlagCanTransfer,
- KMemoryState::FlagCanTransfer, KMemoryPermission::All,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
- KMemoryAttribute::None, perm, KMemoryAttribute::Locked));
-}
-
-Result KPageTable::UnlockForTransferMemory(KProcessAddress address, size_t size,
- const KPageGroup& pg) {
- R_RETURN(this->UnlockMemory(address, size, KMemoryState::FlagCanTransfer,
- KMemoryState::FlagCanTransfer, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::Locked, std::addressof(pg)));
-}
-
-Result KPageTable::LockForCodeMemory(KPageGroup* out, KProcessAddress addr, size_t size) {
- R_RETURN(this->LockMemoryAndOpen(
- out, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory,
- KMemoryPermission::All, KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
- KMemoryAttribute::None, KMemoryPermission::NotMapped | KMemoryPermission::KernelReadWrite,
- KMemoryAttribute::Locked));
-}
-
-Result KPageTable::UnlockForCodeMemory(KProcessAddress addr, size_t size, const KPageGroup& pg) {
- R_RETURN(this->UnlockMemory(
- addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory,
- KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, KMemoryAttribute::Locked, &pg));
-}
-
-bool KPageTable::IsRegionContiguous(KProcessAddress addr, u64 size) const {
- auto start_ptr = m_system.DeviceMemory().GetPointer<u8>(GetInteger(addr));
- for (u64 offset{}; offset < size; offset += PageSize) {
- if (start_ptr != m_system.DeviceMemory().GetPointer<u8>(GetInteger(addr) + offset)) {
- return false;
- }
- start_ptr += PageSize;
- }
- return true;
-}
-
-void KPageTable::AddRegionToPages(KProcessAddress start, size_t num_pages,
- KPageGroup& page_linked_list) {
- KProcessAddress addr{start};
- while (addr < start + (num_pages * PageSize)) {
- const KPhysicalAddress paddr{GetPhysicalAddr(addr)};
- ASSERT(paddr != 0);
- page_linked_list.AddBlock(paddr, 1);
- addr += PageSize;
- }
-}
-
-KProcessAddress KPageTable::AllocateVirtualMemory(KProcessAddress start, size_t region_num_pages,
- u64 needed_num_pages, size_t align) {
- if (m_enable_aslr) {
- UNIMPLEMENTED();
- }
- return m_memory_block_manager.FindFreeArea(start, region_num_pages, needed_num_pages, align, 0,
- IsKernel() ? 1 : 4);
-}
-
-Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, const KPageGroup& page_group,
- OperationType operation) {
- ASSERT(this->IsLockedByCurrentThread());
-
- ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
- ASSERT(num_pages > 0);
- ASSERT(num_pages == page_group.GetNumPages());
-
- switch (operation) {
- case OperationType::MapGroup:
- case OperationType::MapFirstGroup: {
- // We want to maintain a new reference to every page in the group.
- KScopedPageGroup spg(page_group, operation != OperationType::MapFirstGroup);
-
- for (const auto& node : page_group) {
- const size_t size{node.GetNumPages() * PageSize};
-
- // Map the pages.
- m_memory->MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
-
- addr += size;
- }
-
- // We succeeded! We want to persist the reference to the pages.
- spg.CancelClose();
-
- break;
- }
- default:
- ASSERT(false);
- break;
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::Operate(KProcessAddress addr, size_t num_pages, KMemoryPermission perm,
- OperationType operation, KPhysicalAddress map_addr) {
- ASSERT(this->IsLockedByCurrentThread());
-
- ASSERT(num_pages > 0);
- ASSERT(Common::IsAligned(GetInteger(addr), PageSize));
- ASSERT(ContainsPages(addr, num_pages));
-
- switch (operation) {
- case OperationType::Unmap: {
- // Ensure that any pages we track close on exit.
- KPageGroup pages_to_close{m_kernel, this->GetBlockInfoManager()};
- SCOPE_EXIT({ pages_to_close.CloseAndReset(); });
-
- this->AddRegionToPages(addr, num_pages, pages_to_close);
- m_memory->UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
- break;
- }
- case OperationType::Map: {
- ASSERT(map_addr);
- ASSERT(Common::IsAligned(GetInteger(map_addr), PageSize));
- m_memory->MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
-
- // Open references to pages, if we should.
- if (IsHeapPhysicalAddress(m_kernel.MemoryLayout(), map_addr)) {
- m_kernel.MemoryManager().Open(map_addr, num_pages);
- }
- break;
- }
- case OperationType::Separate: {
- // HACK: Unimplemented.
- break;
- }
- case OperationType::ChangePermissions:
- case OperationType::ChangePermissionsAndRefresh:
- case OperationType::ChangePermissionsAndRefreshAndFlush:
- break;
- default:
- ASSERT(false);
- break;
- }
- R_SUCCEED();
-}
-
-void KPageTable::FinalizeUpdate(PageLinkedList* page_list) {
- while (page_list->Peek()) {
- [[maybe_unused]] auto page = page_list->Pop();
-
- // TODO(bunnei): Free pages once they are allocated in guest memory
- // ASSERT(this->GetPageTableManager().IsInPageTableHeap(page));
- // ASSERT(this->GetPageTableManager().GetRefCount(page) == 0);
- // this->GetPageTableManager().Free(page);
- }
-}
-
-KProcessAddress KPageTable::GetRegionAddress(Svc::MemoryState state) const {
- switch (state) {
- case Svc::MemoryState::Free:
- case Svc::MemoryState::Kernel:
- return m_address_space_start;
- case Svc::MemoryState::Normal:
- return m_heap_region_start;
- case Svc::MemoryState::Ipc:
- case Svc::MemoryState::NonSecureIpc:
- case Svc::MemoryState::NonDeviceIpc:
- return m_alias_region_start;
- case Svc::MemoryState::Stack:
- return m_stack_region_start;
- case Svc::MemoryState::Static:
- case Svc::MemoryState::ThreadLocal:
- return m_kernel_map_region_start;
- case Svc::MemoryState::Io:
- case Svc::MemoryState::Shared:
- case Svc::MemoryState::AliasCode:
- case Svc::MemoryState::AliasCodeData:
- case Svc::MemoryState::Transfered:
- case Svc::MemoryState::SharedTransfered:
- case Svc::MemoryState::SharedCode:
- case Svc::MemoryState::GeneratedCode:
- case Svc::MemoryState::CodeOut:
- case Svc::MemoryState::Coverage:
- case Svc::MemoryState::Insecure:
- return m_alias_code_region_start;
- case Svc::MemoryState::Code:
- case Svc::MemoryState::CodeData:
- return m_code_region_start;
- default:
- UNREACHABLE();
- }
-}
-
-size_t KPageTable::GetRegionSize(Svc::MemoryState state) const {
- switch (state) {
- case Svc::MemoryState::Free:
- case Svc::MemoryState::Kernel:
- return m_address_space_end - m_address_space_start;
- case Svc::MemoryState::Normal:
- return m_heap_region_end - m_heap_region_start;
- case Svc::MemoryState::Ipc:
- case Svc::MemoryState::NonSecureIpc:
- case Svc::MemoryState::NonDeviceIpc:
- return m_alias_region_end - m_alias_region_start;
- case Svc::MemoryState::Stack:
- return m_stack_region_end - m_stack_region_start;
- case Svc::MemoryState::Static:
- case Svc::MemoryState::ThreadLocal:
- return m_kernel_map_region_end - m_kernel_map_region_start;
- case Svc::MemoryState::Io:
- case Svc::MemoryState::Shared:
- case Svc::MemoryState::AliasCode:
- case Svc::MemoryState::AliasCodeData:
- case Svc::MemoryState::Transfered:
- case Svc::MemoryState::SharedTransfered:
- case Svc::MemoryState::SharedCode:
- case Svc::MemoryState::GeneratedCode:
- case Svc::MemoryState::CodeOut:
- case Svc::MemoryState::Coverage:
- case Svc::MemoryState::Insecure:
- return m_alias_code_region_end - m_alias_code_region_start;
- case Svc::MemoryState::Code:
- case Svc::MemoryState::CodeData:
- return m_code_region_end - m_code_region_start;
- default:
- UNREACHABLE();
- }
-}
-
-bool KPageTable::CanContain(KProcessAddress addr, size_t size, Svc::MemoryState state) const {
- const KProcessAddress end = addr + size;
- const KProcessAddress last = end - 1;
-
- const KProcessAddress region_start = this->GetRegionAddress(state);
- const size_t region_size = this->GetRegionSize(state);
-
- const bool is_in_region =
- region_start <= addr && addr < end && last <= region_start + region_size - 1;
- const bool is_in_heap = !(end <= m_heap_region_start || m_heap_region_end <= addr ||
- m_heap_region_start == m_heap_region_end);
- const bool is_in_alias = !(end <= m_alias_region_start || m_alias_region_end <= addr ||
- m_alias_region_start == m_alias_region_end);
- switch (state) {
- case Svc::MemoryState::Free:
- case Svc::MemoryState::Kernel:
- return is_in_region;
- case Svc::MemoryState::Io:
- case Svc::MemoryState::Static:
- case Svc::MemoryState::Code:
- case Svc::MemoryState::CodeData:
- case Svc::MemoryState::Shared:
- case Svc::MemoryState::AliasCode:
- case Svc::MemoryState::AliasCodeData:
- case Svc::MemoryState::Stack:
- case Svc::MemoryState::ThreadLocal:
- case Svc::MemoryState::Transfered:
- case Svc::MemoryState::SharedTransfered:
- case Svc::MemoryState::SharedCode:
- case Svc::MemoryState::GeneratedCode:
- case Svc::MemoryState::CodeOut:
- case Svc::MemoryState::Coverage:
- case Svc::MemoryState::Insecure:
- return is_in_region && !is_in_heap && !is_in_alias;
- case Svc::MemoryState::Normal:
- ASSERT(is_in_heap);
- return is_in_region && !is_in_alias;
- case Svc::MemoryState::Ipc:
- case Svc::MemoryState::NonSecureIpc:
- case Svc::MemoryState::NonDeviceIpc:
- ASSERT(is_in_alias);
- return is_in_region && !is_in_heap;
- default:
- return false;
- }
-}
-
-Result KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr) const {
- // Validate the states match expectation.
- R_UNLESS((info.m_state & state_mask) == state, ResultInvalidCurrentMemory);
- R_UNLESS((info.m_permission & perm_mask) == perm, ResultInvalidCurrentMemory);
- R_UNLESS((info.m_attribute & attr_mask) == attr, ResultInvalidCurrentMemory);
-
- R_SUCCEED();
-}
-
-Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr,
- size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr) const {
- ASSERT(this->IsLockedByCurrentThread());
-
- // Get information about the first block.
- const KProcessAddress last_addr = addr + size - 1;
- KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
- KMemoryInfo info = it->GetMemoryInfo();
-
- // If the start address isn't aligned, we need a block.
- const size_t blocks_for_start_align =
- (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0;
-
- while (true) {
- // Validate against the provided masks.
- R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr));
-
- // Break once we're done.
- if (last_addr <= info.GetLastAddress()) {
- break;
- }
-
- // Advance our iterator.
- it++;
- ASSERT(it != m_memory_block_manager.cend());
- info = it->GetMemoryInfo();
- }
-
- // If the end address isn't aligned, we need a block.
- const size_t blocks_for_end_align =
- (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0;
-
- if (out_blocks_needed != nullptr) {
- *out_blocks_needed = blocks_for_start_align + blocks_for_end_align;
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
- KMemoryAttribute* out_attr, size_t* out_blocks_needed,
- KMemoryBlockManager::const_iterator it,
- KProcessAddress last_addr, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr, KMemoryAttribute ignore_attr) const {
- ASSERT(this->IsLockedByCurrentThread());
-
- // Get information about the first block.
- KMemoryInfo info = it->GetMemoryInfo();
-
- // Validate all blocks in the range have correct state.
- const KMemoryState first_state = info.m_state;
- const KMemoryPermission first_perm = info.m_permission;
- const KMemoryAttribute first_attr = info.m_attribute;
- while (true) {
- // Validate the current block.
- R_UNLESS(info.m_state == first_state, ResultInvalidCurrentMemory);
- R_UNLESS(info.m_permission == first_perm, ResultInvalidCurrentMemory);
- R_UNLESS((info.m_attribute | ignore_attr) == (first_attr | ignore_attr),
- ResultInvalidCurrentMemory);
-
- // Validate against the provided masks.
- R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr));
-
- // Break once we're done.
- if (last_addr <= info.GetLastAddress()) {
- break;
- }
-
- // Advance our iterator.
- it++;
- ASSERT(it != m_memory_block_manager.cend());
- info = it->GetMemoryInfo();
- }
-
- // Write output state.
- if (out_state != nullptr) {
- *out_state = first_state;
- }
- if (out_perm != nullptr) {
- *out_perm = first_perm;
- }
- if (out_attr != nullptr) {
- *out_attr = static_cast<KMemoryAttribute>(first_attr & ~ignore_attr);
- }
-
- // If the end address isn't aligned, we need a block.
- if (out_blocks_needed != nullptr) {
- const size_t blocks_for_end_align =
- (Common::AlignDown(GetInteger(last_addr), PageSize) + PageSize != info.GetEndAddress())
- ? 1
- : 0;
- *out_blocks_needed = blocks_for_end_align;
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
- KMemoryAttribute* out_attr, size_t* out_blocks_needed,
- KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr, KMemoryAttribute ignore_attr) const {
- ASSERT(this->IsLockedByCurrentThread());
-
- // Check memory state.
- const KProcessAddress last_addr = addr + size - 1;
- KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
- R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr,
- state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr));
-
- // If the start address isn't aligned, we need a block.
- if (out_blocks_needed != nullptr &&
- Common::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) {
- ++(*out_blocks_needed);
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_KPhysicalAddress,
- KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr, KMemoryPermission new_perm,
- KMemoryAttribute lock_attr) {
- // Validate basic preconditions.
- ASSERT((lock_attr & attr) == KMemoryAttribute::None);
- ASSERT((lock_attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
- KMemoryAttribute::None);
-
- // Validate the lock request.
- const size_t num_pages = size / PageSize;
- R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check that the output page group is empty, if it exists.
- if (out_pg) {
- ASSERT(out_pg->GetNumPages() == 0);
- }
-
- // Check the state.
- KMemoryState old_state{};
- KMemoryPermission old_perm{};
- KMemoryAttribute old_attr{};
- size_t num_allocator_blocks{};
- R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm),
- std::addressof(old_attr), std::addressof(num_allocator_blocks),
- addr, size, state_mask | KMemoryState::FlagReferenceCounted,
- state | KMemoryState::FlagReferenceCounted, perm_mask, perm,
- attr_mask, attr));
-
- // Get the physical address, if we're supposed to.
- if (out_KPhysicalAddress != nullptr) {
- ASSERT(this->GetPhysicalAddressLocked(out_KPhysicalAddress, addr));
- }
-
- // Make the page group, if we're supposed to.
- if (out_pg != nullptr) {
- R_TRY(this->MakePageGroup(*out_pg, addr, num_pages));
- }
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Decide on new perm and attr.
- new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm;
- KMemoryAttribute new_attr = static_cast<KMemoryAttribute>(old_attr | lock_attr);
-
- // Update permission, if we need to.
- if (new_perm != old_perm) {
- R_TRY(Operate(addr, num_pages, new_perm, OperationType::ChangePermissions));
- }
-
- // Apply the memory block updates.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
- new_attr, KMemoryBlockDisableMergeAttribute::Locked,
- KMemoryBlockDisableMergeAttribute::None);
-
- // If we have an output page group, open.
- if (out_pg) {
- out_pg->Open();
- }
-
- R_SUCCEED();
-}
-
-Result KPageTable::UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr, KMemoryPermission new_perm,
- KMemoryAttribute lock_attr, const KPageGroup* pg) {
- // Validate basic preconditions.
- ASSERT((attr_mask & lock_attr) == lock_attr);
- ASSERT((attr & lock_attr) == lock_attr);
-
- // Validate the unlock request.
- const size_t num_pages = size / PageSize;
- R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory);
-
- // Lock the table.
- KScopedLightLock lk(m_general_lock);
-
- // Check the state.
- KMemoryState old_state{};
- KMemoryPermission old_perm{};
- KMemoryAttribute old_attr{};
- size_t num_allocator_blocks{};
- R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm),
- std::addressof(old_attr), std::addressof(num_allocator_blocks),
- addr, size, state_mask | KMemoryState::FlagReferenceCounted,
- state | KMemoryState::FlagReferenceCounted, perm_mask, perm,
- attr_mask, attr));
-
- // Check the page group.
- if (pg != nullptr) {
- R_UNLESS(this->IsValidPageGroup(*pg, addr, num_pages), ResultInvalidMemoryRegion);
- }
-
- // Decide on new perm and attr.
- new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm;
- KMemoryAttribute new_attr = static_cast<KMemoryAttribute>(old_attr & ~lock_attr);
-
- // Create an update allocator.
- Result allocator_result{ResultSuccess};
- KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
- m_memory_block_slab_manager, num_allocator_blocks);
- R_TRY(allocator_result);
-
- // Update permission, if we need to.
- if (new_perm != old_perm) {
- R_TRY(Operate(addr, num_pages, new_perm, OperationType::ChangePermissions));
- }
-
- // Apply the memory block updates.
- m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
- new_attr, KMemoryBlockDisableMergeAttribute::None,
- KMemoryBlockDisableMergeAttribute::Locked);
-
- R_SUCCEED();
-}
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 66f16faaf..5541bc13f 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -3,548 +3,14 @@
#pragma once
-#include <memory>
-
-#include "common/common_funcs.h"
-#include "common/page_table.h"
-#include "core/file_sys/program_metadata.h"
-#include "core/hle/kernel/k_dynamic_resource_manager.h"
-#include "core/hle/kernel/k_light_lock.h"
-#include "core/hle/kernel/k_memory_block.h"
-#include "core/hle/kernel/k_memory_block_manager.h"
-#include "core/hle/kernel/k_memory_layout.h"
-#include "core/hle/kernel/k_memory_manager.h"
-#include "core/hle/kernel/k_typed_address.h"
-#include "core/hle/result.h"
-#include "core/memory.h"
-
-namespace Core {
-class System;
-}
+#include "core/hle/kernel/k_page_table_base.h"
namespace Kernel {
-enum class DisableMergeAttribute : u8 {
- None = (0U << 0),
- DisableHead = (1U << 0),
- DisableHeadAndBody = (1U << 1),
- EnableHeadAndBody = (1U << 2),
- DisableTail = (1U << 3),
- EnableTail = (1U << 4),
- EnableAndMergeHeadBodyTail = (1U << 5),
- EnableHeadBodyTail = EnableHeadAndBody | EnableTail,
- DisableHeadBodyTail = DisableHeadAndBody | DisableTail,
-};
-
-struct KPageProperties {
- KMemoryPermission perm;
- bool io;
- bool uncached;
- DisableMergeAttribute disable_merge_attributes;
-};
-static_assert(std::is_trivial_v<KPageProperties>);
-static_assert(sizeof(KPageProperties) == sizeof(u32));
-
-class KBlockInfoManager;
-class KMemoryBlockManager;
-class KResourceLimit;
-class KSystemResource;
-
-class KPageTable final {
-protected:
- struct PageLinkedList;
-
-public:
- enum class ICacheInvalidationStrategy : u32 { InvalidateRange, InvalidateAll };
-
- YUZU_NON_COPYABLE(KPageTable);
- YUZU_NON_MOVEABLE(KPageTable);
-
- explicit KPageTable(Core::System& system_);
- ~KPageTable();
-
- Result InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr,
- bool enable_das_merge, bool from_back, KMemoryManager::Pool pool,
- KProcessAddress code_addr, size_t code_size,
- KSystemResource* system_resource, KResourceLimit* resource_limit,
- Core::Memory::Memory& memory);
-
- void Finalize();
-
- Result MapProcessCode(KProcessAddress addr, size_t pages_count, KMemoryState state,
- KMemoryPermission perm);
- Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
- Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size,
- ICacheInvalidationStrategy icache_invalidation_strategy);
- Result UnmapProcessMemory(KProcessAddress dst_addr, size_t size, KPageTable& src_page_table,
- KProcessAddress src_addr);
- Result MapPhysicalMemory(KProcessAddress addr, size_t size);
- Result UnmapPhysicalMemory(KProcessAddress addr, size_t size);
- Result MapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size);
- Result UnmapMemory(KProcessAddress dst_addr, KProcessAddress src_addr, size_t size);
- Result SetProcessMemoryPermission(KProcessAddress addr, size_t size,
- Svc::MemoryPermission svc_perm);
- KMemoryInfo QueryInfo(KProcessAddress addr);
- Result SetMemoryPermission(KProcessAddress addr, size_t size, Svc::MemoryPermission perm);
- Result SetMemoryAttribute(KProcessAddress addr, size_t size, u32 mask, u32 attr);
- Result SetMaxHeapSize(size_t size);
- Result SetHeapSize(u64* out, size_t size);
- Result LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address, size_t size,
- KMemoryPermission perm, bool is_aligned, bool check_heap);
- Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap);
-
- Result UnlockForDeviceAddressSpace(KProcessAddress addr, size_t size);
-
- Result LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address, size_t size);
- Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size);
-
- Result SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr,
- KPageTable& src_page_table, KMemoryPermission test_perm,
- KMemoryState dst_state, bool send);
- Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state);
- Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state);
-
- Result LockForTransferMemory(KPageGroup* out, KProcessAddress address, size_t size,
- KMemoryPermission perm);
- Result UnlockForTransferMemory(KProcessAddress address, size_t size, const KPageGroup& pg);
- Result LockForCodeMemory(KPageGroup* out, KProcessAddress addr, size_t size);
- Result UnlockForCodeMemory(KProcessAddress addr, size_t size, const KPageGroup& pg);
- Result MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages,
- KMemoryState state_mask, KMemoryState state,
- KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr);
-
- Common::PageTable& PageTableImpl() {
- return *m_page_table_impl;
- }
-
- const Common::PageTable& PageTableImpl() const {
- return *m_page_table_impl;
- }
-
- KBlockInfoManager* GetBlockInfoManager() {
- return m_block_info_manager;
- }
-
- Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
- KPhysicalAddress phys_addr, KProcessAddress region_start,
- size_t region_num_pages, KMemoryState state, KMemoryPermission perm) {
- R_RETURN(this->MapPages(out_addr, num_pages, alignment, phys_addr, true, region_start,
- region_num_pages, state, perm));
- }
-
- Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
- KPhysicalAddress phys_addr, KMemoryState state, KMemoryPermission perm) {
- R_RETURN(this->MapPages(out_addr, num_pages, alignment, phys_addr, true,
- this->GetRegionAddress(state),
- this->GetRegionSize(state) / PageSize, state, perm));
- }
-
- Result MapPages(KProcessAddress* out_addr, size_t num_pages, KMemoryState state,
- KMemoryPermission perm) {
- R_RETURN(this->MapPages(out_addr, num_pages, PageSize, 0, false,
- this->GetRegionAddress(state),
- this->GetRegionSize(state) / PageSize, state, perm));
- }
-
- Result MapPages(KProcessAddress address, size_t num_pages, KMemoryState state,
- KMemoryPermission perm);
- Result UnmapPages(KProcessAddress address, size_t num_pages, KMemoryState state);
-
- Result MapPageGroup(KProcessAddress* out_addr, const KPageGroup& pg,
- KProcessAddress region_start, size_t region_num_pages, KMemoryState state,
- KMemoryPermission perm);
- Result MapPageGroup(KProcessAddress address, const KPageGroup& pg, KMemoryState state,
- KMemoryPermission perm);
- Result UnmapPageGroup(KProcessAddress address, const KPageGroup& pg, KMemoryState state);
- void RemapPageGroup(PageLinkedList* page_list, KProcessAddress address, size_t size,
- const KPageGroup& pg);
-
- KProcessAddress GetRegionAddress(Svc::MemoryState state) const;
- size_t GetRegionSize(Svc::MemoryState state) const;
- bool CanContain(KProcessAddress addr, size_t size, Svc::MemoryState state) const;
-
- KProcessAddress GetRegionAddress(KMemoryState state) const {
- return this->GetRegionAddress(static_cast<Svc::MemoryState>(state & KMemoryState::Mask));
- }
- size_t GetRegionSize(KMemoryState state) const {
- return this->GetRegionSize(static_cast<Svc::MemoryState>(state & KMemoryState::Mask));
- }
- bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const {
- return this->CanContain(addr, size,
- static_cast<Svc::MemoryState>(state & KMemoryState::Mask));
- }
-
-protected:
- struct PageLinkedList {
- private:
- struct Node {
- Node* m_next;
- std::array<u8, PageSize - sizeof(Node*)> m_buffer;
- };
-
- public:
- constexpr PageLinkedList() = default;
-
- void Push(Node* n) {
- ASSERT(Common::IsAligned(reinterpret_cast<uintptr_t>(n), PageSize));
- n->m_next = m_root;
- m_root = n;
- }
-
- void Push(Core::Memory::Memory& memory, KVirtualAddress addr) {
- this->Push(memory.GetPointer<Node>(GetInteger(addr)));
- }
-
- Node* Peek() const {
- return m_root;
- }
-
- Node* Pop() {
- Node* const r = m_root;
-
- m_root = r->m_next;
- r->m_next = nullptr;
-
- return r;
- }
-
- private:
- Node* m_root{};
- };
- static_assert(std::is_trivially_destructible<PageLinkedList>::value);
-
-private:
- enum class OperationType : u32 {
- Map = 0,
- MapGroup = 1,
- MapFirstGroup = 2,
- Unmap = 3,
- ChangePermissions = 4,
- ChangePermissionsAndRefresh = 5,
- ChangePermissionsAndRefreshAndFlush = 6,
- Separate = 7,
- };
-
- static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr =
- KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared;
-
- Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
- KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start,
- size_t region_num_pages, KMemoryState state, KMemoryPermission perm);
- bool IsRegionContiguous(KProcessAddress addr, u64 size) const;
- void AddRegionToPages(KProcessAddress start, size_t num_pages, KPageGroup& page_linked_list);
- KMemoryInfo QueryInfoImpl(KProcessAddress addr);
- KProcessAddress AllocateVirtualMemory(KProcessAddress start, size_t region_num_pages,
- u64 needed_num_pages, size_t align);
- Result Operate(KProcessAddress addr, size_t num_pages, const KPageGroup& page_group,
- OperationType operation);
- Result Operate(KProcessAddress addr, size_t num_pages, KMemoryPermission perm,
- OperationType operation, KPhysicalAddress map_addr = 0);
- void FinalizeUpdate(PageLinkedList* page_list);
-
- KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
- size_t num_pages, size_t alignment, size_t offset,
- size_t guard_pages);
-
- Result CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
- KMemoryState state_mask, KMemoryState state,
- KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
- Result CheckMemoryStateContiguous(KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr) const {
- R_RETURN(this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask,
- perm, attr_mask, attr));
- }
-
- Result CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, KMemoryState state,
- KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
- Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
- KMemoryAttribute* out_attr, size_t* out_blocks_needed,
- KMemoryBlockManager::const_iterator it, KProcessAddress last_addr,
- KMemoryState state_mask, KMemoryState state,
- KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr,
- KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const;
- Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
- KMemoryAttribute* out_attr, size_t* out_blocks_needed,
- KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr,
- KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const;
- Result CheckMemoryState(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
- KMemoryState state_mask, KMemoryState state,
- KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr,
- KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
- R_RETURN(CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size,
- state_mask, state, perm_mask, perm, attr_mask, attr,
- ignore_attr));
- }
- Result CheckMemoryState(KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr,
- KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
- R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm,
- attr_mask, attr, ignore_attr));
- }
-
- Result LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_KPhysicalAddress,
- KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
- KMemoryAttribute attr, KMemoryPermission new_perm,
- KMemoryAttribute lock_attr);
- Result UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
- KMemoryAttribute attr_mask, KMemoryAttribute attr,
- KMemoryPermission new_perm, KMemoryAttribute lock_attr,
- const KPageGroup* pg);
-
- Result MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages);
- bool IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr, size_t num_pages);
-
- bool IsLockedByCurrentThread() const {
- return m_general_lock.IsLockedByCurrentThread();
- }
-
- bool IsHeapPhysicalAddress(const KMemoryLayout& layout, KPhysicalAddress phys_addr) {
- ASSERT(this->IsLockedByCurrentThread());
-
- return layout.IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr);
- }
-
- bool GetPhysicalAddressLocked(KPhysicalAddress* out, KProcessAddress virt_addr) const {
- ASSERT(this->IsLockedByCurrentThread());
-
- *out = GetPhysicalAddr(virt_addr);
-
- return *out != 0;
- }
-
- Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed,
- KProcessAddress address, size_t size, KMemoryPermission test_perm,
- KMemoryState dst_state);
- Result SetupForIpcServer(KProcessAddress* out_addr, size_t size, KProcessAddress src_addr,
- KMemoryPermission test_perm, KMemoryState dst_state,
- KPageTable& src_page_table, bool send);
- void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, KProcessAddress address,
- size_t size, KMemoryPermission prot_perm);
-
- Result AllocateAndMapPagesImpl(PageLinkedList* page_list, KProcessAddress address,
- size_t num_pages, KMemoryPermission perm);
- Result MapPageGroupImpl(PageLinkedList* page_list, KProcessAddress address,
- const KPageGroup& pg, const KPageProperties properties, bool reuse_ll);
-
- mutable KLightLock m_general_lock;
- mutable KLightLock m_map_physical_memory_lock;
-
-public:
- constexpr KProcessAddress GetAddressSpaceStart() const {
- return m_address_space_start;
- }
- constexpr KProcessAddress GetAddressSpaceEnd() const {
- return m_address_space_end;
- }
- constexpr size_t GetAddressSpaceSize() const {
- return m_address_space_end - m_address_space_start;
- }
- constexpr KProcessAddress GetHeapRegionStart() const {
- return m_heap_region_start;
- }
- constexpr KProcessAddress GetHeapRegionEnd() const {
- return m_heap_region_end;
- }
- constexpr size_t GetHeapRegionSize() const {
- return m_heap_region_end - m_heap_region_start;
- }
- constexpr KProcessAddress GetAliasRegionStart() const {
- return m_alias_region_start;
- }
- constexpr KProcessAddress GetAliasRegionEnd() const {
- return m_alias_region_end;
- }
- constexpr size_t GetAliasRegionSize() const {
- return m_alias_region_end - m_alias_region_start;
- }
- constexpr KProcessAddress GetStackRegionStart() const {
- return m_stack_region_start;
- }
- constexpr KProcessAddress GetStackRegionEnd() const {
- return m_stack_region_end;
- }
- constexpr size_t GetStackRegionSize() const {
- return m_stack_region_end - m_stack_region_start;
- }
- constexpr KProcessAddress GetKernelMapRegionStart() const {
- return m_kernel_map_region_start;
- }
- constexpr KProcessAddress GetKernelMapRegionEnd() const {
- return m_kernel_map_region_end;
- }
- constexpr KProcessAddress GetCodeRegionStart() const {
- return m_code_region_start;
- }
- constexpr KProcessAddress GetCodeRegionEnd() const {
- return m_code_region_end;
- }
- constexpr KProcessAddress GetAliasCodeRegionStart() const {
- return m_alias_code_region_start;
- }
- constexpr KProcessAddress GetAliasCodeRegionEnd() const {
- return m_alias_code_region_end;
- }
- constexpr size_t GetAliasCodeRegionSize() const {
- return m_alias_code_region_end - m_alias_code_region_start;
- }
- size_t GetNormalMemorySize() const {
- KScopedLightLock lk(m_general_lock);
- return GetHeapSize() + m_mapped_physical_memory_size;
- }
- constexpr size_t GetAddressSpaceWidth() const {
- return m_address_space_width;
- }
- constexpr size_t GetHeapSize() const {
- return m_current_heap_end - m_heap_region_start;
- }
- constexpr size_t GetNumGuardPages() const {
- return IsKernel() ? 1 : 4;
- }
- KPhysicalAddress GetPhysicalAddr(KProcessAddress addr) const {
- const auto backing_addr = m_page_table_impl->backing_addr[addr >> PageBits];
- ASSERT(backing_addr);
- return backing_addr + GetInteger(addr);
- }
- constexpr bool Contains(KProcessAddress addr) const {
- return m_address_space_start <= addr && addr <= m_address_space_end - 1;
- }
- constexpr bool Contains(KProcessAddress addr, size_t size) const {
- return m_address_space_start <= addr && addr < addr + size &&
- addr + size - 1 <= m_address_space_end - 1;
- }
- constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const {
- return this->Contains(addr, size) && m_alias_region_start <= addr &&
- addr + size - 1 <= m_alias_region_end - 1;
- }
- constexpr bool IsInHeapRegion(KProcessAddress addr, size_t size) const {
- return this->Contains(addr, size) && m_heap_region_start <= addr &&
- addr + size - 1 <= m_heap_region_end - 1;
- }
-
+class KPageTable final : public KPageTableBase {
public:
- static KVirtualAddress GetLinearMappedVirtualAddress(const KMemoryLayout& layout,
- KPhysicalAddress addr) {
- return layout.GetLinearVirtualAddress(addr);
- }
-
- static KPhysicalAddress GetLinearMappedPhysicalAddress(const KMemoryLayout& layout,
- KVirtualAddress addr) {
- return layout.GetLinearPhysicalAddress(addr);
- }
-
- static KVirtualAddress GetHeapVirtualAddress(const KMemoryLayout& layout,
- KPhysicalAddress addr) {
- return GetLinearMappedVirtualAddress(layout, addr);
- }
-
- static KPhysicalAddress GetHeapPhysicalAddress(const KMemoryLayout& layout,
- KVirtualAddress addr) {
- return GetLinearMappedPhysicalAddress(layout, addr);
- }
-
- static KVirtualAddress GetPageTableVirtualAddress(const KMemoryLayout& layout,
- KPhysicalAddress addr) {
- return GetLinearMappedVirtualAddress(layout, addr);
- }
-
- static KPhysicalAddress GetPageTablePhysicalAddress(const KMemoryLayout& layout,
- KVirtualAddress addr) {
- return GetLinearMappedPhysicalAddress(layout, addr);
- }
-
-private:
- constexpr bool IsKernel() const {
- return m_is_kernel;
- }
- constexpr bool IsAslrEnabled() const {
- return m_enable_aslr;
- }
-
- constexpr bool ContainsPages(KProcessAddress addr, size_t num_pages) const {
- return (m_address_space_start <= addr) &&
- (num_pages <= (m_address_space_end - m_address_space_start) / PageSize) &&
- (addr + num_pages * PageSize - 1 <= m_address_space_end - 1);
- }
-
-private:
- class KScopedPageTableUpdater {
- private:
- KPageTable* m_pt{};
- PageLinkedList m_ll;
-
- public:
- explicit KScopedPageTableUpdater(KPageTable* pt) : m_pt(pt) {}
- explicit KScopedPageTableUpdater(KPageTable& pt) : KScopedPageTableUpdater(&pt) {}
- ~KScopedPageTableUpdater() {
- m_pt->FinalizeUpdate(this->GetPageList());
- }
-
- PageLinkedList* GetPageList() {
- return std::addressof(m_ll);
- }
- };
-
-private:
- KProcessAddress m_address_space_start{};
- KProcessAddress m_address_space_end{};
- KProcessAddress m_heap_region_start{};
- KProcessAddress m_heap_region_end{};
- KProcessAddress m_current_heap_end{};
- KProcessAddress m_alias_region_start{};
- KProcessAddress m_alias_region_end{};
- KProcessAddress m_stack_region_start{};
- KProcessAddress m_stack_region_end{};
- KProcessAddress m_kernel_map_region_start{};
- KProcessAddress m_kernel_map_region_end{};
- KProcessAddress m_code_region_start{};
- KProcessAddress m_code_region_end{};
- KProcessAddress m_alias_code_region_start{};
- KProcessAddress m_alias_code_region_end{};
-
- size_t m_max_heap_size{};
- size_t m_mapped_physical_memory_size{};
- size_t m_mapped_unsafe_physical_memory{};
- size_t m_mapped_insecure_memory{};
- size_t m_mapped_ipc_server_memory{};
- size_t m_address_space_width{};
-
- KMemoryBlockManager m_memory_block_manager;
- u32 m_allocate_option{};
-
- bool m_is_kernel{};
- bool m_enable_aslr{};
- bool m_enable_device_address_space_merge{};
-
- KMemoryBlockSlabManager* m_memory_block_slab_manager{};
- KBlockInfoManager* m_block_info_manager{};
- KResourceLimit* m_resource_limit{};
-
- u32 m_heap_fill_value{};
- u32 m_ipc_fill_value{};
- u32 m_stack_fill_value{};
- const KMemoryRegion* m_cached_physical_heap_region{};
-
- KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application};
- KMemoryManager::Direction m_allocation_option{KMemoryManager::Direction::FromFront};
-
- std::unique_ptr<Common::PageTable> m_page_table_impl;
-
- Core::System& m_system;
- KernelCore& m_kernel;
- Core::Memory::Memory* m_memory{};
+ explicit KPageTable(KernelCore& kernel) : KPageTableBase(kernel) {}
+ ~KPageTable() = default;
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp
new file mode 100644
index 000000000..47dc8fd35
--- /dev/null
+++ b/src/core/hle/kernel/k_page_table_base.cpp
@@ -0,0 +1,5716 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/scope_exit.h"
+#include "common/settings.h"
+#include "core/core.h"
+#include "core/hle/kernel/k_address_space_info.h"
+#include "core/hle/kernel/k_page_table_base.h"
+#include "core/hle/kernel/k_scoped_resource_reservation.h"
+#include "core/hle/kernel/k_system_resource.h"
+
+namespace Kernel {
+
+namespace {
+
+class KScopedLightLockPair {
+ YUZU_NON_COPYABLE(KScopedLightLockPair);
+ YUZU_NON_MOVEABLE(KScopedLightLockPair);
+
+private:
+ KLightLock* m_lower;
+ KLightLock* m_upper;
+
+public:
+ KScopedLightLockPair(KLightLock& lhs, KLightLock& rhs) {
+ // Ensure our locks are in a consistent order.
+ if (std::addressof(lhs) <= std::addressof(rhs)) {
+ m_lower = std::addressof(lhs);
+ m_upper = std::addressof(rhs);
+ } else {
+ m_lower = std::addressof(rhs);
+ m_upper = std::addressof(lhs);
+ }
+
+ // Acquire both locks.
+ m_lower->Lock();
+ if (m_lower != m_upper) {
+ m_upper->Lock();
+ }
+ }
+
+ ~KScopedLightLockPair() {
+ // Unlock the upper lock.
+ if (m_upper != nullptr && m_upper != m_lower) {
+ m_upper->Unlock();
+ }
+
+ // Unlock the lower lock.
+ if (m_lower != nullptr) {
+ m_lower->Unlock();
+ }
+ }
+
+public:
+ // Utility.
+ void TryUnlockHalf(KLightLock& lock) {
+ // Only allow unlocking if the lock is half the pair.
+ if (m_lower != m_upper) {
+ // We want to be sure the lock is one we own.
+ if (m_lower == std::addressof(lock)) {
+ lock.Unlock();
+ m_lower = nullptr;
+ } else if (m_upper == std::addressof(lock)) {
+ lock.Unlock();
+ m_upper = nullptr;
+ }
+ }
+ }
+};
+
+template <typename AddressType>
+void InvalidateInstructionCache(Core::System& system, AddressType addr, u64 size) {
+ system.InvalidateCpuInstructionCacheRange(GetInteger(addr), size);
+}
+
+template <typename AddressType>
+Result InvalidateDataCache(AddressType addr, u64 size) {
+ R_SUCCEED();
+}
+
+template <typename AddressType>
+Result StoreDataCache(AddressType addr, u64 size) {
+ R_SUCCEED();
+}
+
+template <typename AddressType>
+Result FlushDataCache(AddressType addr, u64 size) {
+ R_SUCCEED();
+}
+
+} // namespace
+
+void KPageTableBase::MemoryRange::Open() {
+ // If the range contains heap pages, open them.
+ if (this->IsHeap()) {
+ m_kernel.MemoryManager().Open(this->GetAddress(), this->GetSize() / PageSize);
+ }
+}
+
+void KPageTableBase::MemoryRange::Close() {
+ // If the range contains heap pages, close them.
+ if (this->IsHeap()) {
+ m_kernel.MemoryManager().Close(this->GetAddress(), this->GetSize() / PageSize);
+ }
+}
+
+KPageTableBase::KPageTableBase(KernelCore& kernel)
+ : m_kernel(kernel), m_system(kernel.System()), m_general_lock(kernel),
+ m_map_physical_memory_lock(kernel), m_device_map_lock(kernel) {}
+KPageTableBase::~KPageTableBase() = default;
+
+Result KPageTableBase::InitializeForKernel(bool is_64_bit, KVirtualAddress start,
+ KVirtualAddress end, Core::Memory::Memory& memory) {
+ // Initialize our members.
+ m_address_space_width =
+ static_cast<u32>(is_64_bit ? Common::BitSize<u64>() : Common::BitSize<u32>());
+ m_address_space_start = KProcessAddress(GetInteger(start));
+ m_address_space_end = KProcessAddress(GetInteger(end));
+ m_is_kernel = true;
+ m_enable_aslr = true;
+ m_enable_device_address_space_merge = false;
+
+ m_heap_region_start = 0;
+ m_heap_region_end = 0;
+ m_current_heap_end = 0;
+ m_alias_region_start = 0;
+ m_alias_region_end = 0;
+ m_stack_region_start = 0;
+ m_stack_region_end = 0;
+ m_kernel_map_region_start = 0;
+ m_kernel_map_region_end = 0;
+ m_alias_code_region_start = 0;
+ m_alias_code_region_end = 0;
+ m_code_region_start = 0;
+ m_code_region_end = 0;
+ m_max_heap_size = 0;
+ m_mapped_physical_memory_size = 0;
+ m_mapped_unsafe_physical_memory = 0;
+ m_mapped_insecure_memory = 0;
+ m_mapped_ipc_server_memory = 0;
+
+ m_memory_block_slab_manager =
+ m_kernel.GetSystemSystemResource().GetMemoryBlockSlabManagerPointer();
+ m_block_info_manager = m_kernel.GetSystemSystemResource().GetBlockInfoManagerPointer();
+ m_resource_limit = m_kernel.GetSystemResourceLimit();
+
+ m_allocate_option = KMemoryManager::EncodeOption(KMemoryManager::Pool::System,
+ KMemoryManager::Direction::FromFront);
+ m_heap_fill_value = MemoryFillValue_Zero;
+ m_ipc_fill_value = MemoryFillValue_Zero;
+ m_stack_fill_value = MemoryFillValue_Zero;
+
+ m_cached_physical_linear_region = nullptr;
+ m_cached_physical_heap_region = nullptr;
+
+ // Initialize our implementation.
+ m_impl = std::make_unique<Common::PageTable>();
+ m_impl->Resize(m_address_space_width, PageBits);
+
+ // Set the tracking memory.
+ m_memory = std::addressof(memory);
+
+ // Initialize our memory block manager.
+ R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end,
+ m_memory_block_slab_manager));
+}
+
+Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr,
+ bool enable_das_merge, bool from_back,
+ KMemoryManager::Pool pool, KProcessAddress code_address,
+ size_t code_size, KSystemResource* system_resource,
+ KResourceLimit* resource_limit,
+ Core::Memory::Memory& memory) {
+ // Calculate region extents.
+ const size_t as_width = GetAddressSpaceWidth(as_type);
+ const KProcessAddress start = 0;
+ const KProcessAddress end = (1ULL << as_width);
+
+ // Validate the region.
+ ASSERT(start <= code_address);
+ ASSERT(code_address < code_address + code_size);
+ ASSERT(code_address + code_size - 1 <= end - 1);
+
+ // Define helpers.
+ auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) {
+ return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
+ };
+ auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) {
+ return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type);
+ };
+
+ // Set our bit width and heap/alias sizes.
+ m_address_space_width = static_cast<u32>(GetAddressSpaceWidth(as_type));
+ size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Alias);
+ size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Heap);
+
+ // Adjust heap/alias size if we don't have an alias region.
+ if ((as_type & Svc::CreateProcessFlag::AddressSpaceMask) ==
+ Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias) {
+ heap_region_size += alias_region_size;
+ alias_region_size = 0;
+ }
+
+ // Set code regions and determine remaining sizes.
+ KProcessAddress process_code_start;
+ KProcessAddress process_code_end;
+ size_t stack_region_size;
+ size_t kernel_map_region_size;
+ if (m_address_space_width == 39) {
+ alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Alias);
+ heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Heap);
+ stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Stack);
+ kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
+ m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::Map39Bit);
+ m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit);
+ m_alias_code_region_start = m_code_region_start;
+ m_alias_code_region_end = m_code_region_end;
+ process_code_start = Common::AlignDown(GetInteger(code_address), RegionAlignment);
+ process_code_end = Common::AlignUp(GetInteger(code_address) + code_size, RegionAlignment);
+ } else {
+ stack_region_size = 0;
+ kernel_map_region_size = 0;
+ m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::MapSmall);
+ m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
+ m_stack_region_start = m_code_region_start;
+ m_alias_code_region_start = m_code_region_start;
+ m_alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type::MapLarge) +
+ GetSpaceSize(KAddressSpaceInfo::Type::MapLarge);
+ m_stack_region_end = m_code_region_end;
+ m_kernel_map_region_start = m_code_region_start;
+ m_kernel_map_region_end = m_code_region_end;
+ process_code_start = m_code_region_start;
+ process_code_end = m_code_region_end;
+ }
+
+ // Set other basic fields.
+ m_enable_aslr = enable_aslr;
+ m_enable_device_address_space_merge = enable_das_merge;
+ m_address_space_start = start;
+ m_address_space_end = end;
+ m_is_kernel = false;
+ m_memory_block_slab_manager = system_resource->GetMemoryBlockSlabManagerPointer();
+ m_block_info_manager = system_resource->GetBlockInfoManagerPointer();
+ m_resource_limit = resource_limit;
+
+ // Determine the region we can place our undetermineds in.
+ KProcessAddress alloc_start;
+ size_t alloc_size;
+ if ((GetInteger(process_code_start) - GetInteger(m_code_region_start)) >=
+ (GetInteger(end) - GetInteger(process_code_end))) {
+ alloc_start = m_code_region_start;
+ alloc_size = GetInteger(process_code_start) - GetInteger(m_code_region_start);
+ } else {
+ alloc_start = process_code_end;
+ alloc_size = GetInteger(end) - GetInteger(process_code_end);
+ }
+ const size_t needed_size =
+ (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size);
+ R_UNLESS(alloc_size >= needed_size, ResultOutOfMemory);
+
+ const size_t remaining_size = alloc_size - needed_size;
+
+ // Determine random placements for each region.
+ size_t alias_rnd = 0, heap_rnd = 0, stack_rnd = 0, kmap_rnd = 0;
+ if (enable_aslr) {
+ alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
+ RegionAlignment;
+ heap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
+ RegionAlignment;
+ stack_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
+ RegionAlignment;
+ kmap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
+ RegionAlignment;
+ }
+
+ // Setup heap and alias regions.
+ m_alias_region_start = alloc_start + alias_rnd;
+ m_alias_region_end = m_alias_region_start + alias_region_size;
+ m_heap_region_start = alloc_start + heap_rnd;
+ m_heap_region_end = m_heap_region_start + heap_region_size;
+
+ if (alias_rnd <= heap_rnd) {
+ m_heap_region_start += alias_region_size;
+ m_heap_region_end += alias_region_size;
+ } else {
+ m_alias_region_start += heap_region_size;
+ m_alias_region_end += heap_region_size;
+ }
+
+ // Setup stack region.
+ if (stack_region_size) {
+ m_stack_region_start = alloc_start + stack_rnd;
+ m_stack_region_end = m_stack_region_start + stack_region_size;
+
+ if (alias_rnd < stack_rnd) {
+ m_stack_region_start += alias_region_size;
+ m_stack_region_end += alias_region_size;
+ } else {
+ m_alias_region_start += stack_region_size;
+ m_alias_region_end += stack_region_size;
+ }
+
+ if (heap_rnd < stack_rnd) {
+ m_stack_region_start += heap_region_size;
+ m_stack_region_end += heap_region_size;
+ } else {
+ m_heap_region_start += stack_region_size;
+ m_heap_region_end += stack_region_size;
+ }
+ }
+
+ // Setup kernel map region.
+ if (kernel_map_region_size) {
+ m_kernel_map_region_start = alloc_start + kmap_rnd;
+ m_kernel_map_region_end = m_kernel_map_region_start + kernel_map_region_size;
+
+ if (alias_rnd < kmap_rnd) {
+ m_kernel_map_region_start += alias_region_size;
+ m_kernel_map_region_end += alias_region_size;
+ } else {
+ m_alias_region_start += kernel_map_region_size;
+ m_alias_region_end += kernel_map_region_size;
+ }
+
+ if (heap_rnd < kmap_rnd) {
+ m_kernel_map_region_start += heap_region_size;
+ m_kernel_map_region_end += heap_region_size;
+ } else {
+ m_heap_region_start += kernel_map_region_size;
+ m_heap_region_end += kernel_map_region_size;
+ }
+
+ if (stack_region_size) {
+ if (stack_rnd < kmap_rnd) {
+ m_kernel_map_region_start += stack_region_size;
+ m_kernel_map_region_end += stack_region_size;
+ } else {
+ m_stack_region_start += kernel_map_region_size;
+ m_stack_region_end += kernel_map_region_size;
+ }
+ }
+ }
+
+ // Set heap and fill members.
+ m_current_heap_end = m_heap_region_start;
+ m_max_heap_size = 0;
+ m_mapped_physical_memory_size = 0;
+ m_mapped_unsafe_physical_memory = 0;
+ m_mapped_insecure_memory = 0;
+ m_mapped_ipc_server_memory = 0;
+
+ // const bool fill_memory = KTargetSystem::IsDebugMemoryFillEnabled();
+ const bool fill_memory = false;
+ m_heap_fill_value = fill_memory ? MemoryFillValue_Heap : MemoryFillValue_Zero;
+ m_ipc_fill_value = fill_memory ? MemoryFillValue_Ipc : MemoryFillValue_Zero;
+ m_stack_fill_value = fill_memory ? MemoryFillValue_Stack : MemoryFillValue_Zero;
+
+ // Set allocation option.
+ m_allocate_option =
+ KMemoryManager::EncodeOption(pool, from_back ? KMemoryManager::Direction::FromBack
+ : KMemoryManager::Direction::FromFront);
+
+ // Ensure that we regions inside our address space.
+ auto IsInAddressSpace = [&](KProcessAddress addr) {
+ return m_address_space_start <= addr && addr <= m_address_space_end;
+ };
+ ASSERT(IsInAddressSpace(m_alias_region_start));
+ ASSERT(IsInAddressSpace(m_alias_region_end));
+ ASSERT(IsInAddressSpace(m_heap_region_start));
+ ASSERT(IsInAddressSpace(m_heap_region_end));
+ ASSERT(IsInAddressSpace(m_stack_region_start));
+ ASSERT(IsInAddressSpace(m_stack_region_end));
+ ASSERT(IsInAddressSpace(m_kernel_map_region_start));
+ ASSERT(IsInAddressSpace(m_kernel_map_region_end));
+
+ // Ensure that we selected regions that don't overlap.
+ const KProcessAddress alias_start = m_alias_region_start;
+ const KProcessAddress alias_last = m_alias_region_end - 1;
+ const KProcessAddress heap_start = m_heap_region_start;
+ const KProcessAddress heap_last = m_heap_region_end - 1;
+ const KProcessAddress stack_start = m_stack_region_start;
+ const KProcessAddress stack_last = m_stack_region_end - 1;
+ const KProcessAddress kmap_start = m_kernel_map_region_start;
+ const KProcessAddress kmap_last = m_kernel_map_region_end - 1;
+ ASSERT(alias_last < heap_start || heap_last < alias_start);
+ ASSERT(alias_last < stack_start || stack_last < alias_start);
+ ASSERT(alias_last < kmap_start || kmap_last < alias_start);
+ ASSERT(heap_last < stack_start || stack_last < heap_start);
+ ASSERT(heap_last < kmap_start || kmap_last < heap_start);
+
+ // Initialize our implementation.
+ m_impl = std::make_unique<Common::PageTable>();
+ m_impl->Resize(m_address_space_width, PageBits);
+
+ // Set the tracking memory.
+ m_memory = std::addressof(memory);
+
+ // Initialize our memory block manager.
+ R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end,
+ m_memory_block_slab_manager));
+}
+
+void KPageTableBase::Finalize() {
+ auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) {
+ if (Settings::IsFastmemEnabled()) {
+ m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size);
+ }
+ };
+
+ // Finalize memory blocks.
+ m_memory_block_manager.Finalize(m_memory_block_slab_manager, std::move(HostUnmapCallback));
+
+ // Free any unsafe mapped memory.
+ if (m_mapped_unsafe_physical_memory) {
+ UNIMPLEMENTED();
+ }
+
+ // Release any insecure mapped memory.
+ if (m_mapped_insecure_memory) {
+ if (auto* const insecure_resource_limit =
+ KSystemControl::GetInsecureMemoryResourceLimit(m_kernel);
+ insecure_resource_limit != nullptr) {
+ insecure_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax,
+ m_mapped_insecure_memory);
+ }
+ }
+
+ // Release any ipc server memory.
+ if (m_mapped_ipc_server_memory) {
+ m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax,
+ m_mapped_ipc_server_memory);
+ }
+
+ // Close the backing page table, as the destructor is not called for guest objects.
+ m_impl.reset();
+}
+
+KProcessAddress KPageTableBase::GetRegionAddress(Svc::MemoryState state) const {
+ switch (state) {
+ case Svc::MemoryState::Free:
+ case Svc::MemoryState::Kernel:
+ return m_address_space_start;
+ case Svc::MemoryState::Normal:
+ return m_heap_region_start;
+ case Svc::MemoryState::Ipc:
+ case Svc::MemoryState::NonSecureIpc:
+ case Svc::MemoryState::NonDeviceIpc:
+ return m_alias_region_start;
+ case Svc::MemoryState::Stack:
+ return m_stack_region_start;
+ case Svc::MemoryState::Static:
+ case Svc::MemoryState::ThreadLocal:
+ return m_kernel_map_region_start;
+ case Svc::MemoryState::Io:
+ case Svc::MemoryState::Shared:
+ case Svc::MemoryState::AliasCode:
+ case Svc::MemoryState::AliasCodeData:
+ case Svc::MemoryState::Transfered:
+ case Svc::MemoryState::SharedTransfered:
+ case Svc::MemoryState::SharedCode:
+ case Svc::MemoryState::GeneratedCode:
+ case Svc::MemoryState::CodeOut:
+ case Svc::MemoryState::Coverage:
+ case Svc::MemoryState::Insecure:
+ return m_alias_code_region_start;
+ case Svc::MemoryState::Code:
+ case Svc::MemoryState::CodeData:
+ return m_code_region_start;
+ default:
+ UNREACHABLE();
+ }
+}
+
+size_t KPageTableBase::GetRegionSize(Svc::MemoryState state) const {
+ switch (state) {
+ case Svc::MemoryState::Free:
+ case Svc::MemoryState::Kernel:
+ return m_address_space_end - m_address_space_start;
+ case Svc::MemoryState::Normal:
+ return m_heap_region_end - m_heap_region_start;
+ case Svc::MemoryState::Ipc:
+ case Svc::MemoryState::NonSecureIpc:
+ case Svc::MemoryState::NonDeviceIpc:
+ return m_alias_region_end - m_alias_region_start;
+ case Svc::MemoryState::Stack:
+ return m_stack_region_end - m_stack_region_start;
+ case Svc::MemoryState::Static:
+ case Svc::MemoryState::ThreadLocal:
+ return m_kernel_map_region_end - m_kernel_map_region_start;
+ case Svc::MemoryState::Io:
+ case Svc::MemoryState::Shared:
+ case Svc::MemoryState::AliasCode:
+ case Svc::MemoryState::AliasCodeData:
+ case Svc::MemoryState::Transfered:
+ case Svc::MemoryState::SharedTransfered:
+ case Svc::MemoryState::SharedCode:
+ case Svc::MemoryState::GeneratedCode:
+ case Svc::MemoryState::CodeOut:
+ case Svc::MemoryState::Coverage:
+ case Svc::MemoryState::Insecure:
+ return m_alias_code_region_end - m_alias_code_region_start;
+ case Svc::MemoryState::Code:
+ case Svc::MemoryState::CodeData:
+ return m_code_region_end - m_code_region_start;
+ default:
+ UNREACHABLE();
+ }
+}
+
+bool KPageTableBase::CanContain(KProcessAddress addr, size_t size, Svc::MemoryState state) const {
+ const KProcessAddress end = addr + size;
+ const KProcessAddress last = end - 1;
+
+ const KProcessAddress region_start = this->GetRegionAddress(state);
+ const size_t region_size = this->GetRegionSize(state);
+
+ const bool is_in_region =
+ region_start <= addr && addr < end && last <= region_start + region_size - 1;
+ const bool is_in_heap = !(end <= m_heap_region_start || m_heap_region_end <= addr ||
+ m_heap_region_start == m_heap_region_end);
+ const bool is_in_alias = !(end <= m_alias_region_start || m_alias_region_end <= addr ||
+ m_alias_region_start == m_alias_region_end);
+ switch (state) {
+ case Svc::MemoryState::Free:
+ case Svc::MemoryState::Kernel:
+ return is_in_region;
+ case Svc::MemoryState::Io:
+ case Svc::MemoryState::Static:
+ case Svc::MemoryState::Code:
+ case Svc::MemoryState::CodeData:
+ case Svc::MemoryState::Shared:
+ case Svc::MemoryState::AliasCode:
+ case Svc::MemoryState::AliasCodeData:
+ case Svc::MemoryState::Stack:
+ case Svc::MemoryState::ThreadLocal:
+ case Svc::MemoryState::Transfered:
+ case Svc::MemoryState::SharedTransfered:
+ case Svc::MemoryState::SharedCode:
+ case Svc::MemoryState::GeneratedCode:
+ case Svc::MemoryState::CodeOut:
+ case Svc::MemoryState::Coverage:
+ case Svc::MemoryState::Insecure:
+ return is_in_region && !is_in_heap && !is_in_alias;
+ case Svc::MemoryState::Normal:
+ ASSERT(is_in_heap);
+ return is_in_region && !is_in_alias;
+ case Svc::MemoryState::Ipc:
+ case Svc::MemoryState::NonSecureIpc:
+ case Svc::MemoryState::NonDeviceIpc:
+ ASSERT(is_in_alias);
+ return is_in_region && !is_in_heap;
+ default:
+ return false;
+ }
+}
+
+Result KPageTableBase::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm, KMemoryAttribute attr_mask,
+ KMemoryAttribute attr) const {
+ // Validate the states match expectation.
+ R_UNLESS((info.m_state & state_mask) == state, ResultInvalidCurrentMemory);
+ R_UNLESS((info.m_permission & perm_mask) == perm, ResultInvalidCurrentMemory);
+ R_UNLESS((info.m_attribute & attr_mask) == attr, ResultInvalidCurrentMemory);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr,
+ size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm,
+ KMemoryAttribute attr_mask,
+ KMemoryAttribute attr) const {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Get information about the first block.
+ const KProcessAddress last_addr = addr + size - 1;
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
+ KMemoryInfo info = it->GetMemoryInfo();
+
+ // If the start address isn't aligned, we need a block.
+ const size_t blocks_for_start_align =
+ (Common::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0;
+
+ while (true) {
+ // Validate against the provided masks.
+ R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr));
+
+ // Break once we're done.
+ if (last_addr <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance our iterator.
+ it++;
+ ASSERT(it != m_memory_block_manager.cend());
+ info = it->GetMemoryInfo();
+ }
+
+ // If the end address isn't aligned, we need a block.
+ const size_t blocks_for_end_align =
+ (Common::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0;
+
+ if (out_blocks_needed != nullptr) {
+ *out_blocks_needed = blocks_for_start_align + blocks_for_end_align;
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
+ KMemoryAttribute* out_attr, size_t* out_blocks_needed,
+ KMemoryBlockManager::const_iterator it,
+ KProcessAddress last_addr, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm, KMemoryAttribute attr_mask,
+ KMemoryAttribute attr, KMemoryAttribute ignore_attr) const {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Get information about the first block.
+ KMemoryInfo info = it->GetMemoryInfo();
+
+ // Validate all blocks in the range have correct state.
+ const KMemoryState first_state = info.m_state;
+ const KMemoryPermission first_perm = info.m_permission;
+ const KMemoryAttribute first_attr = info.m_attribute;
+ while (true) {
+ // Validate the current block.
+ R_UNLESS(info.m_state == first_state, ResultInvalidCurrentMemory);
+ R_UNLESS(info.m_permission == first_perm, ResultInvalidCurrentMemory);
+ R_UNLESS((info.m_attribute | ignore_attr) == (first_attr | ignore_attr),
+ ResultInvalidCurrentMemory);
+
+ // Validate against the provided masks.
+ R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr));
+
+ // Break once we're done.
+ if (last_addr <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance our iterator.
+ it++;
+ ASSERT(it != m_memory_block_manager.cend());
+ info = it->GetMemoryInfo();
+ }
+
+ // Write output state.
+ if (out_state != nullptr) {
+ *out_state = first_state;
+ }
+ if (out_perm != nullptr) {
+ *out_perm = first_perm;
+ }
+ if (out_attr != nullptr) {
+ *out_attr = first_attr & ~ignore_attr;
+ }
+
+ // If the end address isn't aligned, we need a block.
+ if (out_blocks_needed != nullptr) {
+ const size_t blocks_for_end_align =
+ (Common::AlignDown(GetInteger(last_addr), PageSize) + PageSize != info.GetEndAddress())
+ ? 1
+ : 0;
+ *out_blocks_needed = blocks_for_end_align;
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
+ KMemoryAttribute* out_attr, size_t* out_blocks_needed,
+ KProcessAddress addr, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm, KMemoryAttribute attr_mask,
+ KMemoryAttribute attr, KMemoryAttribute ignore_attr) const {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Check memory state.
+ const KProcessAddress last_addr = addr + size - 1;
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
+ R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr,
+ state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr));
+
+ // If the start address isn't aligned, we need a block.
+ if (out_blocks_needed != nullptr &&
+ Common::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) {
+ ++(*out_blocks_needed);
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_paddr,
+ KProcessAddress addr, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm, KMemoryAttribute attr_mask,
+ KMemoryAttribute attr, KMemoryPermission new_perm,
+ KMemoryAttribute lock_attr) {
+ // Validate basic preconditions.
+ ASSERT(False(lock_attr & attr));
+ ASSERT(False(lock_attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)));
+
+ // Validate the lock request.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check that the output page group is empty, if it exists.
+ if (out_pg) {
+ ASSERT(out_pg->GetNumPages() == 0);
+ }
+
+ // Check the state.
+ KMemoryState old_state;
+ KMemoryPermission old_perm;
+ KMemoryAttribute old_attr;
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm),
+ std::addressof(old_attr), std::addressof(num_allocator_blocks),
+ addr, size, state_mask | KMemoryState::FlagReferenceCounted,
+ state | KMemoryState::FlagReferenceCounted, perm_mask, perm,
+ attr_mask, attr));
+
+ // Get the physical address, if we're supposed to.
+ if (out_paddr != nullptr) {
+ ASSERT(this->GetPhysicalAddressLocked(out_paddr, addr));
+ }
+
+ // Make the page group, if we're supposed to.
+ if (out_pg != nullptr) {
+ R_TRY(this->MakePageGroup(*out_pg, addr, num_pages));
+ }
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Decide on new perm and attr.
+ new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm;
+ KMemoryAttribute new_attr = old_attr | static_cast<KMemoryAttribute>(lock_attr);
+
+ // Update permission, if we need to.
+ if (new_perm != old_perm) {
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ const KPageProperties properties = {new_perm, false,
+ True(old_attr & KMemoryAttribute::Uncached),
+ DisableMergeAttribute::DisableHeadBodyTail};
+ R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, 0, false, properties,
+ OperationType::ChangePermissions, false));
+ }
+
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
+ new_attr, KMemoryBlockDisableMergeAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // If we have an output group, open.
+ if (out_pg) {
+ out_pg->Open();
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm, KMemoryAttribute attr_mask,
+ KMemoryAttribute attr, KMemoryPermission new_perm,
+ KMemoryAttribute lock_attr, const KPageGroup* pg) {
+ // Validate basic preconditions.
+ ASSERT((attr_mask & lock_attr) == lock_attr);
+ ASSERT((attr & lock_attr) == lock_attr);
+
+ // Validate the unlock request.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the state.
+ KMemoryState old_state;
+ KMemoryPermission old_perm;
+ KMemoryAttribute old_attr;
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm),
+ std::addressof(old_attr), std::addressof(num_allocator_blocks),
+ addr, size, state_mask | KMemoryState::FlagReferenceCounted,
+ state | KMemoryState::FlagReferenceCounted, perm_mask, perm,
+ attr_mask, attr));
+
+ // Check the page group.
+ if (pg != nullptr) {
+ R_UNLESS(this->IsValidPageGroup(*pg, addr, num_pages), ResultInvalidMemoryRegion);
+ }
+
+ // Decide on new perm and attr.
+ new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm;
+ KMemoryAttribute new_attr = old_attr & ~static_cast<KMemoryAttribute>(lock_attr);
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Update permission, if we need to.
+ if (new_perm != old_perm) {
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ const KPageProperties properties = {new_perm, false,
+ True(old_attr & KMemoryAttribute::Uncached),
+ DisableMergeAttribute::EnableAndMergeHeadBodyTail};
+ R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, 0, false, properties,
+ OperationType::ChangePermissions, false));
+ }
+
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
+ new_attr, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Locked);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::QueryInfoImpl(KMemoryInfo* out_info, Svc::PageInfo* out_page,
+ KProcessAddress address) const {
+ ASSERT(this->IsLockedByCurrentThread());
+ ASSERT(out_info != nullptr);
+ ASSERT(out_page != nullptr);
+
+ const KMemoryBlock* block = m_memory_block_manager.FindBlock(address);
+ R_UNLESS(block != nullptr, ResultInvalidCurrentMemory);
+
+ *out_info = block->GetMemoryInfo();
+ out_page->flags = 0;
+ R_SUCCEED();
+}
+
+Result KPageTableBase::QueryMappingImpl(KProcessAddress* out, KPhysicalAddress address, size_t size,
+ Svc::MemoryState state) const {
+ ASSERT(!this->IsLockedByCurrentThread());
+ ASSERT(out != nullptr);
+
+ const KProcessAddress region_start = this->GetRegionAddress(state);
+ const size_t region_size = this->GetRegionSize(state);
+
+ // Check that the address/size are potentially valid.
+ R_UNLESS((address < address + size), ResultNotFound);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry cur_entry = {.phys_addr = 0, .block_size = 0};
+ bool cur_valid = false;
+ TraversalEntry next_entry;
+ bool next_valid;
+ size_t tot_size = 0;
+
+ next_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), region_start);
+ next_entry.block_size =
+ (next_entry.block_size - (GetInteger(region_start) & (next_entry.block_size - 1)));
+
+ // Iterate, looking for entry.
+ while (true) {
+ if ((!next_valid && !cur_valid) ||
+ (next_valid && cur_valid &&
+ next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size)) {
+ cur_entry.block_size += next_entry.block_size;
+ } else {
+ if (cur_valid && cur_entry.phys_addr <= address &&
+ address + size <= cur_entry.phys_addr + cur_entry.block_size) {
+ // Check if this region is valid.
+ const KProcessAddress mapped_address =
+ (region_start + tot_size) + GetInteger(address - cur_entry.phys_addr);
+ if (R_SUCCEEDED(this->CheckMemoryState(
+ mapped_address, size, KMemoryState::Mask, static_cast<KMemoryState>(state),
+ KMemoryPermission::UserRead, KMemoryPermission::UserRead,
+ KMemoryAttribute::None, KMemoryAttribute::None))) {
+ // It is!
+ *out = mapped_address;
+ R_SUCCEED();
+ }
+ }
+
+ // Update tracking variables.
+ tot_size += cur_entry.block_size;
+ cur_entry = next_entry;
+ cur_valid = next_valid;
+ }
+
+ if (cur_entry.block_size + tot_size >= region_size) {
+ break;
+ }
+
+ next_valid = impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ }
+
+ // Check the last entry.
+ R_UNLESS(cur_valid, ResultNotFound);
+ R_UNLESS(cur_entry.phys_addr <= address, ResultNotFound);
+ R_UNLESS(address + size <= cur_entry.phys_addr + cur_entry.block_size, ResultNotFound);
+
+ // Check if the last region is valid.
+ const KProcessAddress mapped_address =
+ (region_start + tot_size) + GetInteger(address - cur_entry.phys_addr);
+ R_TRY_CATCH(this->CheckMemoryState(mapped_address, size, KMemoryState::All,
+ static_cast<KMemoryState>(state),
+ KMemoryPermission::UserRead, KMemoryPermission::UserRead,
+ KMemoryAttribute::None, KMemoryAttribute::None)) {
+ R_CONVERT_ALL(ResultNotFound);
+ }
+ R_END_TRY_CATCH;
+
+ // We found the region.
+ *out = mapped_address;
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate that the source address's state is valid.
+ KMemoryState src_state;
+ size_t num_src_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(src_state), nullptr, nullptr,
+ std::addressof(num_src_allocator_blocks), src_address, size,
+ KMemoryState::FlagCanAlias, KMemoryState::FlagCanAlias,
+ KMemoryPermission::All, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::All, KMemoryAttribute::None));
+
+ // Validate that the dst address's state is valid.
+ size_t num_dst_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_dst_allocator_blocks), dst_address, size,
+ KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+
+ // Create an update allocator for the source.
+ Result src_allocator_result;
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
+
+ // Create an update allocator for the destination.
+ Result dst_allocator_result;
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
+
+ // Map the memory.
+ {
+ // Determine the number of pages being operated on.
+ const size_t num_pages = size / PageSize;
+
+ // Create page groups for the memory being unmapped.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+
+ // Create the page group representing the source.
+ R_TRY(this->MakePageGroup(pg, src_address, num_pages));
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Reprotect the source as kernel-read/not mapped.
+ const KMemoryPermission new_src_perm = static_cast<KMemoryPermission>(
+ KMemoryPermission::KernelRead | KMemoryPermission::NotMapped);
+ const KMemoryAttribute new_src_attr = KMemoryAttribute::Locked;
+ const KPageProperties src_properties = {new_src_perm, false, false,
+ DisableMergeAttribute::DisableHeadBodyTail};
+ R_TRY(this->Operate(updater.GetPageList(), src_address, num_pages, 0, false, src_properties,
+ OperationType::ChangePermissions, false));
+
+ // Ensure that we unprotect the source pages on failure.
+ ON_RESULT_FAILURE {
+ const KPageProperties unprotect_properties = {
+ KMemoryPermission::UserReadWrite, false, false,
+ DisableMergeAttribute::EnableHeadBodyTail};
+ R_ASSERT(this->Operate(updater.GetPageList(), src_address, num_pages, 0, false,
+ unprotect_properties, OperationType::ChangePermissions, true));
+ };
+
+ // Map the alias pages.
+ const KPageProperties dst_map_properties = {KMemoryPermission::UserReadWrite, false, false,
+ DisableMergeAttribute::DisableHead};
+ R_TRY(this->MapPageGroupImpl(updater.GetPageList(), dst_address, pg, dst_map_properties,
+ false));
+
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(std::addressof(src_allocator), src_address, num_pages,
+ src_state, new_src_perm, new_src_attr,
+ KMemoryBlockDisableMergeAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::None);
+ m_memory_block_manager.Update(
+ std::addressof(dst_allocator), dst_address, num_pages, KMemoryState::Stack,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal, KMemoryBlockDisableMergeAttribute::None);
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnmapMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate that the source address's state is valid.
+ KMemoryState src_state;
+ size_t num_src_allocator_blocks;
+ R_TRY(this->CheckMemoryState(
+ std::addressof(src_state), nullptr, nullptr, std::addressof(num_src_allocator_blocks),
+ src_address, size, KMemoryState::FlagCanAlias, KMemoryState::FlagCanAlias,
+ KMemoryPermission::All, KMemoryPermission::NotMapped | KMemoryPermission::KernelRead,
+ KMemoryAttribute::All, KMemoryAttribute::Locked));
+
+ // Validate that the dst address's state is valid.
+ KMemoryPermission dst_perm;
+ size_t num_dst_allocator_blocks;
+ R_TRY(this->CheckMemoryState(
+ nullptr, std::addressof(dst_perm), nullptr, std::addressof(num_dst_allocator_blocks),
+ dst_address, size, KMemoryState::All, KMemoryState::Stack, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::None));
+
+ // Create an update allocator for the source.
+ Result src_allocator_result;
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
+
+ // Create an update allocator for the destination.
+ Result dst_allocator_result;
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
+
+ // Unmap the memory.
+ {
+ // Determine the number of pages being operated on.
+ const size_t num_pages = size / PageSize;
+
+ // Create page groups for the memory being unmapped.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+
+ // Create the page group representing the destination.
+ R_TRY(this->MakePageGroup(pg, dst_address, num_pages));
+
+ // Ensure the page group is the valid for the source.
+ R_UNLESS(this->IsValidPageGroup(pg, src_address, num_pages), ResultInvalidMemoryRegion);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Unmap the aliased copy of the pages.
+ const KPageProperties dst_unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), dst_address, num_pages, 0, false,
+ dst_unmap_properties, OperationType::Unmap, false));
+
+ // Ensure that we re-map the aliased pages on failure.
+ ON_RESULT_FAILURE {
+ this->RemapPageGroup(updater.GetPageList(), dst_address, size, pg);
+ };
+
+ // Try to set the permissions for the source pages back to what they should be.
+ const KPageProperties src_properties = {KMemoryPermission::UserReadWrite, false, false,
+ DisableMergeAttribute::EnableAndMergeHeadBodyTail};
+ R_TRY(this->Operate(updater.GetPageList(), src_address, num_pages, 0, false, src_properties,
+ OperationType::ChangePermissions, false));
+
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(
+ std::addressof(src_allocator), src_address, num_pages, src_state,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Locked);
+ m_memory_block_manager.Update(
+ std::addressof(dst_allocator), dst_address, num_pages, KMemoryState::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Normal);
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size) {
+ // Validate the mapping request.
+ R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
+ ResultInvalidMemoryRegion);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Verify that the source memory is normal heap.
+ KMemoryState src_state;
+ KMemoryPermission src_perm;
+ size_t num_src_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(src_state), std::addressof(src_perm), nullptr,
+ std::addressof(num_src_allocator_blocks), src_address, size,
+ KMemoryState::All, KMemoryState::Normal, KMemoryPermission::All,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
+ KMemoryAttribute::None));
+
+ // Verify that the destination memory is unmapped.
+ size_t num_dst_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_dst_allocator_blocks), dst_address, size,
+ KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+
+ // Create an update allocator for the source.
+ Result src_allocator_result;
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
+
+ // Create an update allocator for the destination.
+ Result dst_allocator_result;
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
+
+ // Map the code memory.
+ {
+ // Determine the number of pages being operated on.
+ const size_t num_pages = size / PageSize;
+
+ // Create page groups for the memory being unmapped.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+
+ // Create the page group representing the source.
+ R_TRY(this->MakePageGroup(pg, src_address, num_pages));
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Reprotect the source as kernel-read/not mapped.
+ const KMemoryPermission new_perm = static_cast<KMemoryPermission>(
+ KMemoryPermission::KernelRead | KMemoryPermission::NotMapped);
+ const KPageProperties src_properties = {new_perm, false, false,
+ DisableMergeAttribute::DisableHeadBodyTail};
+ R_TRY(this->Operate(updater.GetPageList(), src_address, num_pages, 0, false, src_properties,
+ OperationType::ChangePermissions, false));
+
+ // Ensure that we unprotect the source pages on failure.
+ ON_RESULT_FAILURE {
+ const KPageProperties unprotect_properties = {
+ src_perm, false, false, DisableMergeAttribute::EnableHeadBodyTail};
+ R_ASSERT(this->Operate(updater.GetPageList(), src_address, num_pages, 0, false,
+ unprotect_properties, OperationType::ChangePermissions, true));
+ };
+
+ // Map the alias pages.
+ const KPageProperties dst_properties = {new_perm, false, false,
+ DisableMergeAttribute::DisableHead};
+ R_TRY(
+ this->MapPageGroupImpl(updater.GetPageList(), dst_address, pg, dst_properties, false));
+
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(std::addressof(src_allocator), src_address, num_pages,
+ src_state, new_perm, KMemoryAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::None);
+ m_memory_block_manager.Update(std::addressof(dst_allocator), dst_address, num_pages,
+ KMemoryState::AliasCode, new_perm, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size) {
+ // Validate the mapping request.
+ R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
+ ResultInvalidMemoryRegion);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Verify that the source memory is locked normal heap.
+ size_t num_src_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_src_allocator_blocks), src_address, size,
+ KMemoryState::All, KMemoryState::Normal, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::Locked));
+
+ // Verify that the destination memory is aliasable code.
+ size_t num_dst_allocator_blocks;
+ R_TRY(this->CheckMemoryStateContiguous(
+ std::addressof(num_dst_allocator_blocks), dst_address, size, KMemoryState::FlagCanCodeAlias,
+ KMemoryState::FlagCanCodeAlias, KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::All & ~KMemoryAttribute::PermissionLocked, KMemoryAttribute::None));
+
+ // Determine whether any pages being unmapped are code.
+ bool any_code_pages = false;
+ {
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(dst_address);
+ while (true) {
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // Check if the memory has code flag.
+ if (True(info.GetState() & KMemoryState::FlagCode)) {
+ any_code_pages = true;
+ break;
+ }
+
+ // Check if we're done.
+ if (dst_address + size - 1 <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ ++it;
+ }
+ }
+
+ // Ensure that we maintain the instruction cache.
+ bool reprotected_pages = false;
+ SCOPE_EXIT({
+ if (reprotected_pages && any_code_pages) {
+ InvalidateInstructionCache(m_system, dst_address, size);
+ }
+ });
+
+ // Unmap.
+ {
+ // Determine the number of pages being operated on.
+ const size_t num_pages = size / PageSize;
+
+ // Create page groups for the memory being unmapped.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+
+ // Create the page group representing the destination.
+ R_TRY(this->MakePageGroup(pg, dst_address, num_pages));
+
+ // Verify that the page group contains the same pages as the source.
+ R_UNLESS(this->IsValidPageGroup(pg, src_address, num_pages), ResultInvalidMemoryRegion);
+
+ // Create an update allocator for the source.
+ Result src_allocator_result;
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
+
+ // Create an update allocator for the destination.
+ Result dst_allocator_result;
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Unmap the aliased copy of the pages.
+ const KPageProperties dst_unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), dst_address, num_pages, 0, false,
+ dst_unmap_properties, OperationType::Unmap, false));
+
+ // Ensure that we re-map the aliased pages on failure.
+ ON_RESULT_FAILURE {
+ this->RemapPageGroup(updater.GetPageList(), dst_address, size, pg);
+ };
+
+ // Try to set the permissions for the source pages back to what they should be.
+ const KPageProperties src_properties = {KMemoryPermission::UserReadWrite, false, false,
+ DisableMergeAttribute::EnableAndMergeHeadBodyTail};
+ R_TRY(this->Operate(updater.GetPageList(), src_address, num_pages, 0, false, src_properties,
+ OperationType::ChangePermissions, false));
+
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(
+ std::addressof(dst_allocator), dst_address, num_pages, KMemoryState::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Normal);
+ m_memory_block_manager.Update(
+ std::addressof(src_allocator), src_address, num_pages, KMemoryState::Normal,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Locked);
+
+ // Note that we reprotected pages.
+ reprotected_pages = true;
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapInsecureMemory(KProcessAddress address, size_t size) {
+ // Get the insecure memory resource limit and pool.
+ auto* const insecure_resource_limit = KSystemControl::GetInsecureMemoryResourceLimit(m_kernel);
+ const auto insecure_pool =
+ static_cast<KMemoryManager::Pool>(KSystemControl::GetInsecureMemoryPool());
+
+ // Reserve the insecure memory.
+ // NOTE: ResultOutOfMemory is returned here instead of the usual LimitReached.
+ KScopedResourceReservation memory_reservation(insecure_resource_limit,
+ Svc::LimitableResource::PhysicalMemoryMax, size);
+ R_UNLESS(memory_reservation.Succeeded(), ResultOutOfMemory);
+
+ // Allocate pages for the insecure memory.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+ R_TRY(m_kernel.MemoryManager().AllocateAndOpen(
+ std::addressof(pg), size / PageSize,
+ KMemoryManager::EncodeOption(insecure_pool, KMemoryManager::Direction::FromFront)));
+
+ // Close the opened pages when we're done with them.
+ // If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed
+ // automatically.
+ SCOPE_EXIT({ pg.Close(); });
+
+ // Clear all the newly allocated pages.
+ for (const auto& it : pg) {
+ std::memset(GetHeapVirtualPointer(m_kernel, it.GetAddress()),
+ static_cast<u32>(m_heap_fill_value), it.GetSize());
+ }
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate that the address's state is valid.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Map the pages.
+ const size_t num_pages = size / PageSize;
+ const KPageProperties map_properties = {KMemoryPermission::UserReadWrite, false, false,
+ DisableMergeAttribute::DisableHead};
+ R_TRY(this->Operate(updater.GetPageList(), address, num_pages, pg, map_properties,
+ OperationType::MapGroup, false));
+
+ // Apply the memory block update.
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages,
+ KMemoryState::Insecure, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // Update our mapped insecure size.
+ m_mapped_insecure_memory += size;
+
+ // Commit the memory reservation.
+ memory_reservation.Commit();
+
+ // We succeeded.
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnmapInsecureMemory(KProcessAddress address, size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::All, KMemoryState::Insecure, KMemoryPermission::All,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
+ KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Unmap the memory.
+ const size_t num_pages = size / PageSize;
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), address, num_pages, 0, false, unmap_properties,
+ OperationType::Unmap, false));
+
+ // Apply the memory block update.
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
+
+ // Update our mapped insecure size.
+ m_mapped_insecure_memory -= size;
+
+ // Release the insecure memory from the insecure limit.
+ if (auto* const insecure_resource_limit =
+ KSystemControl::GetInsecureMemoryResourceLimit(m_kernel);
+ insecure_resource_limit != nullptr) {
+ insecure_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, size);
+ }
+
+ R_SUCCEED();
+}
+
+KProcessAddress KPageTableBase::FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
+ size_t num_pages, size_t alignment, size_t offset,
+ size_t guard_pages) const {
+ KProcessAddress address = 0;
+
+ if (num_pages <= region_num_pages) {
+ if (this->IsAslrEnabled()) {
+ // Try to directly find a free area up to 8 times.
+ for (size_t i = 0; i < 8; i++) {
+ const size_t random_offset =
+ KSystemControl::GenerateRandomRange(
+ 0, (region_num_pages - num_pages - guard_pages) * PageSize / alignment) *
+ alignment;
+ const KProcessAddress candidate =
+ Common::AlignDown(GetInteger(region_start + random_offset), alignment) + offset;
+
+ KMemoryInfo info;
+ Svc::PageInfo page_info;
+ R_ASSERT(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info),
+ candidate));
+
+ if (info.m_state != KMemoryState::Free) {
+ continue;
+ }
+ if (!(region_start <= candidate)) {
+ continue;
+ }
+ if (!(info.GetAddress() + guard_pages * PageSize <= GetInteger(candidate))) {
+ continue;
+ }
+ if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <=
+ info.GetLastAddress())) {
+ continue;
+ }
+ if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <=
+ region_start + region_num_pages * PageSize - 1)) {
+ continue;
+ }
+
+ address = candidate;
+ break;
+ }
+ // Fall back to finding the first free area with a random offset.
+ if (address == 0) {
+ // NOTE: Nintendo does not account for guard pages here.
+ // This may theoretically cause an offset to be chosen that cannot be mapped.
+ // We will account for guard pages.
+ const size_t offset_pages = KSystemControl::GenerateRandomRange(
+ 0, region_num_pages - num_pages - guard_pages);
+ address = m_memory_block_manager.FindFreeArea(
+ region_start + offset_pages * PageSize, region_num_pages - offset_pages,
+ num_pages, alignment, offset, guard_pages);
+ }
+ }
+ // Find the first free area.
+ if (address == 0) {
+ address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages,
+ alignment, offset, guard_pages);
+ }
+ }
+
+ return address;
+}
+
+size_t KPageTableBase::GetSize(KMemoryState state) const {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Iterate, counting blocks with the desired state.
+ size_t total_size = 0;
+ for (KMemoryBlockManager::const_iterator it =
+ m_memory_block_manager.FindIterator(m_address_space_start);
+ it != m_memory_block_manager.end(); ++it) {
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+ if (info.GetState() == state) {
+ total_size += info.GetSize();
+ }
+ }
+
+ return total_size;
+}
+
+size_t KPageTableBase::GetCodeSize() const {
+ return this->GetSize(KMemoryState::Code);
+}
+
+size_t KPageTableBase::GetCodeDataSize() const {
+ return this->GetSize(KMemoryState::CodeData);
+}
+
+size_t KPageTableBase::GetAliasCodeSize() const {
+ return this->GetSize(KMemoryState::AliasCode);
+}
+
+size_t KPageTableBase::GetAliasCodeDataSize() const {
+ return this->GetSize(KMemoryState::AliasCodeData);
+}
+
+Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList* page_list, KProcessAddress address,
+ size_t num_pages, KMemoryPermission perm) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Create a page group to hold the pages we allocate.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+
+ // Allocate the pages.
+ R_TRY(
+ m_kernel.MemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, m_allocate_option));
+
+ // Ensure that the page group is closed when we're done working with it.
+ SCOPE_EXIT({ pg.Close(); });
+
+ // Clear all pages.
+ for (const auto& it : pg) {
+ std::memset(GetHeapVirtualPointer(m_kernel, it.GetAddress()),
+ static_cast<u32>(m_heap_fill_value), it.GetSize());
+ }
+
+ // Map the pages.
+ const KPageProperties properties = {perm, false, false, DisableMergeAttribute::None};
+ R_RETURN(this->Operate(page_list, address, num_pages, pg, properties, OperationType::MapGroup,
+ false));
+}
+
+Result KPageTableBase::MapPageGroupImpl(PageLinkedList* page_list, KProcessAddress address,
+ const KPageGroup& pg, const KPageProperties properties,
+ bool reuse_ll) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Note the current address, so that we can iterate.
+ const KProcessAddress start_address = address;
+ KProcessAddress cur_address = address;
+
+ // Ensure that we clean up on failure.
+ ON_RESULT_FAILURE {
+ ASSERT(!reuse_ll);
+ if (cur_address != start_address) {
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_ASSERT(this->Operate(page_list, start_address,
+ (cur_address - start_address) / PageSize, 0, false,
+ unmap_properties, OperationType::Unmap, true));
+ }
+ };
+
+ // Iterate, mapping all pages in the group.
+ for (const auto& block : pg) {
+ // Map and advance.
+ const KPageProperties cur_properties =
+ (cur_address == start_address)
+ ? properties
+ : KPageProperties{properties.perm, properties.io, properties.uncached,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(page_list, cur_address, block.GetNumPages(), block.GetAddress(), true,
+ cur_properties, OperationType::Map, reuse_ll));
+ cur_address += block.GetSize();
+ }
+
+ // We succeeded!
+ R_SUCCEED();
+}
+
+void KPageTableBase::RemapPageGroup(PageLinkedList* page_list, KProcessAddress address, size_t size,
+ const KPageGroup& pg) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Note the current address, so that we can iterate.
+ const KProcessAddress start_address = address;
+ const KProcessAddress last_address = start_address + size - 1;
+ const KProcessAddress end_address = last_address + 1;
+
+ // Iterate over the memory.
+ auto pg_it = pg.begin();
+ ASSERT(pg_it != pg.end());
+
+ KPhysicalAddress pg_phys_addr = pg_it->GetAddress();
+ size_t pg_pages = pg_it->GetNumPages();
+
+ auto it = m_memory_block_manager.FindIterator(start_address);
+ while (true) {
+ // Check that the iterator is valid.
+ ASSERT(it != m_memory_block_manager.end());
+
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // Determine the range to map.
+ KProcessAddress map_address = std::max<u64>(info.GetAddress(), GetInteger(start_address));
+ const KProcessAddress map_end_address =
+ std::min<u64>(info.GetEndAddress(), GetInteger(end_address));
+ ASSERT(map_end_address != map_address);
+
+ // Determine if we should disable head merge.
+ const bool disable_head_merge =
+ info.GetAddress() >= GetInteger(start_address) &&
+ True(info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute::Normal);
+ const KPageProperties map_properties = {
+ info.GetPermission(), false, false,
+ disable_head_merge ? DisableMergeAttribute::DisableHead : DisableMergeAttribute::None};
+
+ // While we have pages to map, map them.
+ size_t map_pages = (map_end_address - map_address) / PageSize;
+ while (map_pages > 0) {
+ // Check if we're at the end of the physical block.
+ if (pg_pages == 0) {
+ // Ensure there are more pages to map.
+ ASSERT(pg_it != pg.end());
+
+ // Advance our physical block.
+ ++pg_it;
+ pg_phys_addr = pg_it->GetAddress();
+ pg_pages = pg_it->GetNumPages();
+ }
+
+ // Map whatever we can.
+ const size_t cur_pages = std::min(pg_pages, map_pages);
+ R_ASSERT(this->Operate(page_list, map_address, map_pages, pg_phys_addr, true,
+ map_properties, OperationType::Map, true));
+
+ // Advance.
+ map_address += cur_pages * PageSize;
+ map_pages -= cur_pages;
+
+ pg_phys_addr += cur_pages * PageSize;
+ pg_pages -= cur_pages;
+ }
+
+ // Check if we're done.
+ if (last_address <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ ++it;
+ }
+
+ // Check that we re-mapped precisely the page group.
+ ASSERT((++pg_it) == pg.end());
+}
+
+Result KPageTableBase::MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ const size_t size = num_pages * PageSize;
+
+ // We're making a new group, not adding to an existing one.
+ R_UNLESS(pg.empty(), ResultInvalidCurrentMemory);
+
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ R_UNLESS(impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), addr),
+ ResultInvalidCurrentMemory);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size = next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ // Iterate, adding to group as we go.
+ while (tot_size < size) {
+ R_UNLESS(impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)),
+ ResultInvalidCurrentMemory);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ const size_t cur_pages = cur_size / PageSize;
+
+ R_UNLESS(IsHeapPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+ R_TRY(pg.AddBlock(cur_addr, cur_pages));
+
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we add the right amount for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // add the last block.
+ const size_t cur_pages = cur_size / PageSize;
+ R_UNLESS(IsHeapPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+ R_TRY(pg.AddBlock(cur_addr, cur_pages));
+
+ R_SUCCEED();
+}
+
+bool KPageTableBase::IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr,
+ size_t num_pages) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ const size_t size = num_pages * PageSize;
+
+ // Empty groups are necessarily invalid.
+ if (pg.empty()) {
+ return false;
+ }
+
+ auto& impl = this->GetImpl();
+
+ // We're going to validate that the group we'd expect is the group we see.
+ auto cur_it = pg.begin();
+ KPhysicalAddress cur_block_address = cur_it->GetAddress();
+ size_t cur_block_pages = cur_it->GetNumPages();
+
+ auto UpdateCurrentIterator = [&]() {
+ if (cur_block_pages == 0) {
+ if ((++cur_it) == pg.end()) {
+ return false;
+ }
+
+ cur_block_address = cur_it->GetAddress();
+ cur_block_pages = cur_it->GetNumPages();
+ }
+ return true;
+ };
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ if (!impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), addr)) {
+ return false;
+ }
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size = next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ // Iterate, comparing expected to actual.
+ while (tot_size < size) {
+ if (!impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context))) {
+ return false;
+ }
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ const size_t cur_pages = cur_size / PageSize;
+
+ if (!IsHeapPhysicalAddress(cur_addr)) {
+ return false;
+ }
+
+ if (!UpdateCurrentIterator()) {
+ return false;
+ }
+
+ if (cur_block_address != cur_addr || cur_block_pages < cur_pages) {
+ return false;
+ }
+
+ cur_block_address += cur_size;
+ cur_block_pages -= cur_pages;
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we compare the right amount for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ if (!IsHeapPhysicalAddress(cur_addr)) {
+ return false;
+ }
+
+ if (!UpdateCurrentIterator()) {
+ return false;
+ }
+
+ return cur_block_address == cur_addr && cur_block_pages == (cur_size / PageSize);
+}
+
+Result KPageTableBase::GetContiguousMemoryRangeWithState(
+ MemoryRange* out, KProcessAddress address, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ auto& impl = this->GetImpl();
+
+ // Begin a traversal.
+ TraversalContext context;
+ TraversalEntry cur_entry = {.phys_addr = 0, .block_size = 0};
+ R_UNLESS(impl.BeginTraversal(std::addressof(cur_entry), std::addressof(context), address),
+ ResultInvalidCurrentMemory);
+
+ // Traverse until we have enough size or we aren't contiguous any more.
+ const KPhysicalAddress phys_address = cur_entry.phys_addr;
+ size_t contig_size;
+ for (contig_size =
+ cur_entry.block_size - (GetInteger(phys_address) & (cur_entry.block_size - 1));
+ contig_size < size; contig_size += cur_entry.block_size) {
+ if (!impl.ContinueTraversal(std::addressof(cur_entry), std::addressof(context))) {
+ break;
+ }
+ if (cur_entry.phys_addr != phys_address + contig_size) {
+ break;
+ }
+ }
+
+ // Take the minimum size for our region.
+ size = std::min(size, contig_size);
+
+ // Check that the memory is contiguous (modulo the reference count bit).
+ const KMemoryState test_state_mask = state_mask | KMemoryState::FlagReferenceCounted;
+ const bool is_heap = R_SUCCEEDED(this->CheckMemoryStateContiguous(
+ address, size, test_state_mask, state | KMemoryState::FlagReferenceCounted, perm_mask, perm,
+ attr_mask, attr));
+ if (!is_heap) {
+ R_TRY(this->CheckMemoryStateContiguous(address, size, test_state_mask, state, perm_mask,
+ perm, attr_mask, attr));
+ }
+
+ // The memory is contiguous, so set the output range.
+ out->Set(phys_address, size, is_heap);
+ R_SUCCEED();
+}
+
+Result KPageTableBase::SetMemoryPermission(KProcessAddress addr, size_t size,
+ Svc::MemoryPermission svc_perm) {
+ const size_t num_pages = size / PageSize;
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Verify we can change the memory permission.
+ KMemoryState old_state;
+ KMemoryPermission old_perm;
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), nullptr,
+ std::addressof(num_allocator_blocks), addr, size,
+ KMemoryState::FlagCanReprotect, KMemoryState::FlagCanReprotect,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::All, KMemoryAttribute::None));
+
+ // Determine new perm.
+ const KMemoryPermission new_perm = ConvertToKMemoryPermission(svc_perm);
+ R_SUCCEED_IF(old_perm == new_perm);
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform mapping operation.
+ const KPageProperties properties = {new_perm, false, false, DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, 0, false, properties,
+ OperationType::ChangePermissions, false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::SetProcessMemoryPermission(KProcessAddress addr, size_t size,
+ Svc::MemoryPermission svc_perm) {
+ const size_t num_pages = size / PageSize;
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Verify we can change the memory permission.
+ KMemoryState old_state;
+ KMemoryPermission old_perm;
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), nullptr,
+ std::addressof(num_allocator_blocks), addr, size,
+ KMemoryState::FlagCode, KMemoryState::FlagCode,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::All, KMemoryAttribute::None));
+
+ // Make a new page group for the region.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+
+ // Determine new perm/state.
+ const KMemoryPermission new_perm = ConvertToKMemoryPermission(svc_perm);
+ KMemoryState new_state = old_state;
+ const bool is_w = (new_perm & KMemoryPermission::UserWrite) == KMemoryPermission::UserWrite;
+ const bool is_x = (new_perm & KMemoryPermission::UserExecute) == KMemoryPermission::UserExecute;
+ const bool was_x =
+ (old_perm & KMemoryPermission::UserExecute) == KMemoryPermission::UserExecute;
+ ASSERT(!(is_w && is_x));
+
+ if (is_w) {
+ switch (old_state) {
+ case KMemoryState::Code:
+ new_state = KMemoryState::CodeData;
+ break;
+ case KMemoryState::AliasCode:
+ new_state = KMemoryState::AliasCodeData;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // Create a page group, if we're setting execute permissions.
+ if (is_x) {
+ R_TRY(this->MakePageGroup(pg, GetInteger(addr), num_pages));
+ }
+
+ // Succeed if there's nothing to do.
+ R_SUCCEED_IF(old_perm == new_perm && old_state == new_state);
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform mapping operation.
+ const KPageProperties properties = {new_perm, false, false, DisableMergeAttribute::None};
+ const auto operation = was_x ? OperationType::ChangePermissionsAndRefreshAndFlush
+ : OperationType::ChangePermissions;
+ R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, 0, false, properties, operation,
+ false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // Ensure cache coherency, if we're setting pages as executable.
+ if (is_x) {
+ for (const auto& block : pg) {
+ StoreDataCache(GetHeapVirtualPointer(m_kernel, block.GetAddress()), block.GetSize());
+ }
+ InvalidateInstructionCache(m_system, addr, size);
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::SetMemoryAttribute(KProcessAddress addr, size_t size, KMemoryAttribute mask,
+ KMemoryAttribute attr) {
+ const size_t num_pages = size / PageSize;
+ ASSERT((mask | KMemoryAttribute::SetMask) == KMemoryAttribute::SetMask);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Verify we can change the memory attribute.
+ KMemoryState old_state;
+ KMemoryPermission old_perm;
+ KMemoryAttribute old_attr;
+ size_t num_allocator_blocks;
+ constexpr KMemoryAttribute AttributeTestMask =
+ ~(KMemoryAttribute::SetMask | KMemoryAttribute::DeviceShared);
+ const KMemoryState state_test_mask =
+ (True(mask & KMemoryAttribute::Uncached) ? KMemoryState::FlagCanChangeAttribute
+ : KMemoryState::None) |
+ (True(mask & KMemoryAttribute::PermissionLocked) ? KMemoryState::FlagCanPermissionLock
+ : KMemoryState::None);
+ R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm),
+ std::addressof(old_attr), std::addressof(num_allocator_blocks),
+ addr, size, state_test_mask, state_test_mask,
+ KMemoryPermission::None, KMemoryPermission::None,
+ AttributeTestMask, KMemoryAttribute::None, ~AttributeTestMask));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // If we need to, perform a change attribute operation.
+ if (True(mask & KMemoryAttribute::Uncached)) {
+ // Determine the new attribute.
+ const KMemoryAttribute new_attr =
+ static_cast<KMemoryAttribute>(((old_attr & ~mask) | (attr & mask)));
+
+ // Perform operation.
+ const KPageProperties properties = {old_perm, false,
+ True(new_attr & KMemoryAttribute::Uncached),
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, 0, false, properties,
+ OperationType::ChangePermissionsAndRefreshAndFlush, false));
+ }
+
+ // Update the blocks.
+ m_memory_block_manager.UpdateAttribute(std::addressof(allocator), addr, num_pages, mask, attr);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::SetHeapSize(KProcessAddress* out, size_t size) {
+ // Lock the physical memory mutex.
+ KScopedLightLock map_phys_mem_lk(m_map_physical_memory_lock);
+
+ // Try to perform a reduction in heap, instead of an extension.
+ KProcessAddress cur_address;
+ size_t allocation_size;
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate that setting heap size is possible at all.
+ R_UNLESS(!m_is_kernel, ResultOutOfMemory);
+ R_UNLESS(size <= static_cast<size_t>(m_heap_region_end - m_heap_region_start),
+ ResultOutOfMemory);
+ R_UNLESS(size <= m_max_heap_size, ResultOutOfMemory);
+
+ if (size < static_cast<size_t>(m_current_heap_end - m_heap_region_start)) {
+ // The size being requested is less than the current size, so we need to free the end of
+ // the heap.
+
+ // Validate memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(
+ std::addressof(num_allocator_blocks), m_heap_region_start + size,
+ (m_current_heap_end - m_heap_region_start) - size, KMemoryState::All,
+ KMemoryState::Normal, KMemoryPermission::All, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::All, KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager,
+ num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Unmap the end of the heap.
+ const size_t num_pages = ((m_current_heap_end - m_heap_region_start) - size) / PageSize;
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), m_heap_region_start + size, num_pages, 0,
+ false, unmap_properties, OperationType::Unmap, false));
+
+ // Release the memory from the resource limit.
+ m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax,
+ num_pages * PageSize);
+
+ // Apply the memory block update.
+ m_memory_block_manager.Update(std::addressof(allocator), m_heap_region_start + size,
+ num_pages, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ size == 0 ? KMemoryBlockDisableMergeAttribute::Normal
+ : KMemoryBlockDisableMergeAttribute::None);
+
+ // Update the current heap end.
+ m_current_heap_end = m_heap_region_start + size;
+
+ // Set the output.
+ *out = m_heap_region_start;
+ R_SUCCEED();
+ } else if (size == static_cast<size_t>(m_current_heap_end - m_heap_region_start)) {
+ // The size requested is exactly the current size.
+ *out = m_heap_region_start;
+ R_SUCCEED();
+ } else {
+ // We have to allocate memory. Determine how much to allocate and where while the table
+ // is locked.
+ cur_address = m_current_heap_end;
+ allocation_size = size - (m_current_heap_end - m_heap_region_start);
+ }
+ }
+
+ // Reserve memory for the heap extension.
+ KScopedResourceReservation memory_reservation(
+ m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, allocation_size);
+ R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
+
+ // Allocate pages for the heap extension.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+ R_TRY(m_kernel.MemoryManager().AllocateAndOpen(std::addressof(pg), allocation_size / PageSize,
+ m_allocate_option));
+
+ // Close the opened pages when we're done with them.
+ // If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed
+ // automatically.
+ SCOPE_EXIT({ pg.Close(); });
+
+ // Clear all the newly allocated pages.
+ for (const auto& it : pg) {
+ std::memset(GetHeapVirtualPointer(m_kernel, it.GetAddress()), m_heap_fill_value,
+ it.GetSize());
+ }
+
+ // Map the pages.
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Ensure that the heap hasn't changed since we began executing.
+ ASSERT(cur_address == m_current_heap_end);
+
+ // Check the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), m_current_heap_end,
+ allocation_size, KMemoryState::All, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(
+ std::addressof(allocator_result), m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Map the pages.
+ const size_t num_pages = allocation_size / PageSize;
+ const KPageProperties map_properties = {KMemoryPermission::UserReadWrite, false, false,
+ (m_current_heap_end == m_heap_region_start)
+ ? DisableMergeAttribute::DisableHead
+ : DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), m_current_heap_end, num_pages, pg,
+ map_properties, OperationType::MapGroup, false));
+
+ // We succeeded, so commit our memory reservation.
+ memory_reservation.Commit();
+
+ // Apply the memory block update.
+ m_memory_block_manager.Update(
+ std::addressof(allocator), m_current_heap_end, num_pages, KMemoryState::Normal,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ m_heap_region_start == m_current_heap_end ? KMemoryBlockDisableMergeAttribute::Normal
+ : KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // Update the current heap end.
+ m_current_heap_end = m_heap_region_start + size;
+
+ // Set the output.
+ *out = m_heap_region_start;
+ R_SUCCEED();
+ }
+}
+
+Result KPageTableBase::SetMaxHeapSize(size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Only process page tables are allowed to set heap size.
+ ASSERT(!this->IsKernel());
+
+ m_max_heap_size = size;
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::QueryInfo(KMemoryInfo* out_info, Svc::PageInfo* out_page_info,
+ KProcessAddress addr) const {
+ // If the address is invalid, create a fake block.
+ if (!this->Contains(addr, 1)) {
+ *out_info = {
+ .m_address = GetInteger(m_address_space_end),
+ .m_size = 0 - GetInteger(m_address_space_end),
+ .m_state = static_cast<KMemoryState>(Svc::MemoryState::Inaccessible),
+ .m_device_disable_merge_left_count = 0,
+ .m_device_disable_merge_right_count = 0,
+ .m_ipc_lock_count = 0,
+ .m_device_use_count = 0,
+ .m_ipc_disable_merge_count = 0,
+ .m_permission = KMemoryPermission::None,
+ .m_attribute = KMemoryAttribute::None,
+ .m_original_permission = KMemoryPermission::None,
+ .m_disable_merge_attribute = KMemoryBlockDisableMergeAttribute::None,
+ };
+ out_page_info->flags = 0;
+
+ R_SUCCEED();
+ }
+
+ // Otherwise, lock the table and query.
+ KScopedLightLock lk(m_general_lock);
+ R_RETURN(this->QueryInfoImpl(out_info, out_page_info, addr));
+}
+
+Result KPageTableBase::QueryPhysicalAddress(Svc::lp64::PhysicalMemoryInfo* out,
+ KProcessAddress address) const {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Align the address down to page size.
+ address = Common::AlignDown(GetInteger(address), PageSize);
+
+ // Verify that we can query the address.
+ KMemoryInfo info;
+ Svc::PageInfo page_info;
+ R_TRY(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info), address));
+
+ // Check the memory state.
+ R_TRY(this->CheckMemoryState(info, KMemoryState::FlagCanQueryPhysical,
+ KMemoryState::FlagCanQueryPhysical,
+ KMemoryPermission::UserReadExecute, KMemoryPermission::UserRead,
+ KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Prepare to traverse.
+ KPhysicalAddress phys_addr;
+ size_t phys_size;
+
+ KProcessAddress virt_addr = info.GetAddress();
+ KProcessAddress end_addr = info.GetEndAddress();
+
+ // Perform traversal.
+ {
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ m_impl->BeginTraversal(std::addressof(next_entry), std::addressof(context), virt_addr);
+ R_UNLESS(traverse_valid, ResultInvalidCurrentMemory);
+
+ // Set tracking variables.
+ phys_addr = next_entry.phys_addr;
+ phys_size = next_entry.block_size - (GetInteger(phys_addr) & (next_entry.block_size - 1));
+
+ // Iterate.
+ while (true) {
+ // Continue the traversal.
+ traverse_valid =
+ m_impl->ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ if (!traverse_valid) {
+ break;
+ }
+
+ if (next_entry.phys_addr != (phys_addr + phys_size)) {
+ // Check if we're done.
+ if (virt_addr <= address && address <= virt_addr + phys_size - 1) {
+ break;
+ }
+
+ // Advance.
+ phys_addr = next_entry.phys_addr;
+ virt_addr += next_entry.block_size;
+ phys_size =
+ next_entry.block_size - (GetInteger(phys_addr) & (next_entry.block_size - 1));
+ } else {
+ phys_size += next_entry.block_size;
+ }
+
+ // Check if we're done.
+ if (end_addr < virt_addr + phys_size) {
+ break;
+ }
+ }
+ ASSERT(virt_addr <= address && address <= virt_addr + phys_size - 1);
+
+ // Ensure we use the right size.
+ if (end_addr < virt_addr + phys_size) {
+ phys_size = end_addr - virt_addr;
+ }
+ }
+
+ // Set the output.
+ out->physical_address = GetInteger(phys_addr);
+ out->virtual_address = GetInteger(virt_addr);
+ out->size = phys_size;
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapIoImpl(KProcessAddress* out, PageLinkedList* page_list,
+ KPhysicalAddress phys_addr, size_t size, KMemoryState state,
+ KMemoryPermission perm) {
+ // Check pre-conditions.
+ ASSERT(this->IsLockedByCurrentThread());
+ ASSERT(Common::IsAligned(GetInteger(phys_addr), PageSize));
+ ASSERT(Common::IsAligned(size, PageSize));
+ ASSERT(size > 0);
+
+ R_UNLESS(phys_addr < phys_addr + size, ResultInvalidAddress);
+ const size_t num_pages = size / PageSize;
+ const KPhysicalAddress last = phys_addr + size - 1;
+
+ // Get region extents.
+ const KProcessAddress region_start = m_kernel_map_region_start;
+ const size_t region_size = m_kernel_map_region_end - m_kernel_map_region_start;
+ const size_t region_num_pages = region_size / PageSize;
+
+ ASSERT(this->CanContain(region_start, region_size, state));
+
+ // Locate the memory region.
+ const KMemoryRegion* region = KMemoryLayout::Find(m_kernel.MemoryLayout(), phys_addr);
+ R_UNLESS(region != nullptr, ResultInvalidAddress);
+
+ ASSERT(region->Contains(GetInteger(phys_addr)));
+
+ // Ensure that the region is mappable.
+ const bool is_rw = perm == KMemoryPermission::UserReadWrite;
+ while (true) {
+ // Check that the region exists.
+ R_UNLESS(region != nullptr, ResultInvalidAddress);
+
+ // Check the region attributes.
+ R_UNLESS(!region->IsDerivedFrom(KMemoryRegionType_Dram), ResultInvalidAddress);
+ R_UNLESS(!region->HasTypeAttribute(KMemoryRegionAttr_UserReadOnly) || !is_rw,
+ ResultInvalidAddress);
+ R_UNLESS(!region->HasTypeAttribute(KMemoryRegionAttr_NoUserMap), ResultInvalidAddress);
+
+ // Check if we're done.
+ if (GetInteger(last) <= region->GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ region = region->GetNext();
+ };
+
+ // Select an address to map at.
+ KProcessAddress addr = 0;
+ {
+ const size_t alignment = 4_KiB;
+ const KPhysicalAddress aligned_phys =
+ Common::AlignUp(GetInteger(phys_addr), alignment) + alignment - 1;
+ R_UNLESS(aligned_phys > phys_addr, ResultInvalidAddress);
+
+ const KPhysicalAddress last_aligned_paddr =
+ Common::AlignDown(GetInteger(last) + 1, alignment) - 1;
+ R_UNLESS((last_aligned_paddr <= last && aligned_phys <= last_aligned_paddr),
+ ResultInvalidAddress);
+
+ addr = this->FindFreeArea(region_start, region_num_pages, num_pages, alignment, 0,
+ this->GetNumGuardPages());
+ R_UNLESS(addr != 0, ResultOutOfMemory);
+ }
+
+ // Check that we can map IO here.
+ ASSERT(this->CanContain(addr, size, state));
+ R_ASSERT(this->CheckMemoryState(addr, size, KMemoryState::All, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Perform mapping operation.
+ const KPageProperties properties = {perm, state == KMemoryState::IoRegister, false,
+ DisableMergeAttribute::DisableHead};
+ R_TRY(this->Operate(page_list, addr, num_pages, phys_addr, true, properties, OperationType::Map,
+ false));
+
+ // Set the output address.
+ *out = addr;
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapIo(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Map the io memory.
+ KProcessAddress addr;
+ R_TRY(this->MapIoImpl(std::addressof(addr), updater.GetPageList(), phys_addr, size,
+ KMemoryState::IoRegister, perm));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, size / PageSize,
+ KMemoryState::IoRegister, perm, KMemoryAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // We successfully mapped the pages.
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr,
+ size_t size, Svc::MemoryMapping mapping,
+ Svc::MemoryPermission svc_perm) {
+ const size_t num_pages = size / PageSize;
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), dst_address, size,
+ KMemoryState::All, KMemoryState::None, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform mapping operation.
+ const KMemoryPermission perm = ConvertToKMemoryPermission(svc_perm);
+ const KPageProperties properties = {perm, mapping == Svc::MemoryMapping::IoRegister,
+ mapping == Svc::MemoryMapping::Uncached,
+ DisableMergeAttribute::DisableHead};
+ R_TRY(this->Operate(updater.GetPageList(), dst_address, num_pages, phys_addr, true, properties,
+ OperationType::Map, false));
+
+ // Update the blocks.
+ const auto state =
+ mapping == Svc::MemoryMapping::Memory ? KMemoryState::IoMemory : KMemoryState::IoRegister;
+ m_memory_block_manager.Update(
+ std::addressof(allocator), dst_address, num_pages, state, perm, KMemoryAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::Normal, KMemoryBlockDisableMergeAttribute::None);
+
+ // We successfully mapped the pages.
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr,
+ size_t size, Svc::MemoryMapping mapping) {
+ const size_t num_pages = size / PageSize;
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate the memory state.
+ KMemoryState old_state;
+ KMemoryPermission old_perm;
+ KMemoryAttribute old_attr;
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(
+ std::addressof(old_state), std::addressof(old_perm), std::addressof(old_attr),
+ std::addressof(num_allocator_blocks), dst_address, size, KMemoryState::All,
+ mapping == Svc::MemoryMapping::Memory ? KMemoryState::IoMemory : KMemoryState::IoRegister,
+ KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::Locked));
+
+ // Validate that the region being unmapped corresponds to the physical range described.
+ {
+ // Get the impl.
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ ASSERT(
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), dst_address));
+
+ // Check that the physical region matches.
+ R_UNLESS(next_entry.phys_addr == phys_addr, ResultInvalidMemoryRegion);
+
+ // Iterate.
+ for (size_t checked_size =
+ next_entry.block_size - (GetInteger(phys_addr) & (next_entry.block_size - 1));
+ checked_size < size; checked_size += next_entry.block_size) {
+ // Continue the traversal.
+ ASSERT(impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)));
+
+ // Check that the physical region matches.
+ R_UNLESS(next_entry.phys_addr == phys_addr + checked_size, ResultInvalidMemoryRegion);
+ }
+ }
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // If the region being unmapped is Memory, synchronize.
+ if (mapping == Svc::MemoryMapping::Memory) {
+ // Change the region to be uncached.
+ const KPageProperties properties = {old_perm, false, true, DisableMergeAttribute::None};
+ R_ASSERT(this->Operate(updater.GetPageList(), dst_address, num_pages, 0, false, properties,
+ OperationType::ChangePermissionsAndRefresh, false));
+
+ // Temporarily unlock ourselves, so that other operations can occur while we flush the
+ // region.
+ m_general_lock.Unlock();
+ SCOPE_EXIT({ m_general_lock.Lock(); });
+
+ // Flush the region.
+ R_ASSERT(FlushDataCache(dst_address, size));
+ }
+
+ // Perform the unmap.
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_ASSERT(this->Operate(updater.GetPageList(), dst_address, num_pages, 0, false,
+ unmap_properties, OperationType::Unmap, false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages,
+ KMemoryState::Free, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) {
+ ASSERT(Common::IsAligned(GetInteger(phys_addr), PageSize));
+ ASSERT(Common::IsAligned(size, PageSize));
+ ASSERT(size > 0);
+ R_UNLESS(phys_addr < phys_addr + size, ResultInvalidAddress);
+ const size_t num_pages = size / PageSize;
+ const KPhysicalAddress last = phys_addr + size - 1;
+
+ // Get region extents.
+ const KProcessAddress region_start = this->GetRegionAddress(KMemoryState::Static);
+ const size_t region_size = this->GetRegionSize(KMemoryState::Static);
+ const size_t region_num_pages = region_size / PageSize;
+
+ // Locate the memory region.
+ const KMemoryRegion* region = KMemoryLayout::Find(m_kernel.MemoryLayout(), phys_addr);
+ R_UNLESS(region != nullptr, ResultInvalidAddress);
+
+ ASSERT(region->Contains(GetInteger(phys_addr)));
+ R_UNLESS(GetInteger(last) <= region->GetLastAddress(), ResultInvalidAddress);
+
+ // Check the region attributes.
+ const bool is_rw = perm == KMemoryPermission::UserReadWrite;
+ R_UNLESS(region->IsDerivedFrom(KMemoryRegionType_Dram), ResultInvalidAddress);
+ R_UNLESS(!region->HasTypeAttribute(KMemoryRegionAttr_NoUserMap), ResultInvalidAddress);
+ R_UNLESS(!region->HasTypeAttribute(KMemoryRegionAttr_UserReadOnly) || !is_rw,
+ ResultInvalidAddress);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Select an address to map at.
+ KProcessAddress addr = 0;
+ {
+ const size_t alignment = 4_KiB;
+ const KPhysicalAddress aligned_phys =
+ Common::AlignUp(GetInteger(phys_addr), alignment) + alignment - 1;
+ R_UNLESS(aligned_phys > phys_addr, ResultInvalidAddress);
+
+ const KPhysicalAddress last_aligned_paddr =
+ Common::AlignDown(GetInteger(last) + 1, alignment) - 1;
+ R_UNLESS((last_aligned_paddr <= last && aligned_phys <= last_aligned_paddr),
+ ResultInvalidAddress);
+
+ addr = this->FindFreeArea(region_start, region_num_pages, num_pages, alignment, 0,
+ this->GetNumGuardPages());
+ R_UNLESS(addr != 0, ResultOutOfMemory);
+ }
+
+ // Check that we can map static here.
+ ASSERT(this->CanContain(addr, size, KMemoryState::Static));
+ R_ASSERT(this->CheckMemoryState(addr, size, KMemoryState::All, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform mapping operation.
+ const KPageProperties properties = {perm, false, false, DisableMergeAttribute::DisableHead};
+ R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, phys_addr, true, properties,
+ OperationType::Map, false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, KMemoryState::Static,
+ perm, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // We successfully mapped the pages.
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapRegion(KMemoryRegionType region_type, KMemoryPermission perm) {
+ // Get the memory region.
+ const KMemoryRegion* region =
+ m_kernel.MemoryLayout().GetPhysicalMemoryRegionTree().FindFirstDerived(region_type);
+ R_UNLESS(region != nullptr, ResultOutOfRange);
+
+ // Check that the region is valid.
+ ASSERT(region->GetEndAddress() != 0);
+
+ // Map the region.
+ R_TRY_CATCH(this->MapStatic(region->GetAddress(), region->GetSize(), perm)){
+ R_CONVERT(ResultInvalidAddress, ResultOutOfRange)} R_END_TRY_CATCH;
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
+ KPhysicalAddress phys_addr, bool is_pa_valid,
+ KProcessAddress region_start, size_t region_num_pages,
+ KMemoryState state, KMemoryPermission perm) {
+ ASSERT(Common::IsAligned(alignment, PageSize) && alignment >= PageSize);
+
+ // Ensure this is a valid map request.
+ R_UNLESS(this->CanContain(region_start, region_num_pages * PageSize, state),
+ ResultInvalidCurrentMemory);
+ R_UNLESS(num_pages < region_num_pages, ResultOutOfMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Find a random address to map at.
+ KProcessAddress addr = this->FindFreeArea(region_start, region_num_pages, num_pages, alignment,
+ 0, this->GetNumGuardPages());
+ R_UNLESS(addr != 0, ResultOutOfMemory);
+ ASSERT(Common::IsAligned(GetInteger(addr), alignment));
+ ASSERT(this->CanContain(addr, num_pages * PageSize, state));
+ R_ASSERT(this->CheckMemoryState(
+ addr, num_pages * PageSize, KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform mapping operation.
+ if (is_pa_valid) {
+ const KPageProperties properties = {perm, false, false, DisableMergeAttribute::DisableHead};
+ R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, phys_addr, true, properties,
+ OperationType::Map, false));
+ } else {
+ R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), addr, num_pages, perm));
+ }
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // We successfully mapped the pages.
+ *out_addr = addr;
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapPages(KProcessAddress address, size_t num_pages, KMemoryState state,
+ KMemoryPermission perm) {
+ // Check that the map is in range.
+ const size_t size = num_pages * PageSize;
+ R_UNLESS(this->CanContain(address, size, state), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Map the pages.
+ R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), address, num_pages, perm));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnmapPages(KProcessAddress address, size_t num_pages, KMemoryState state) {
+ // Check that the unmap is in range.
+ const size_t size = num_pages * PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::All, state, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform the unmap.
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), address, num_pages, 0, false, unmap_properties,
+ OperationType::Unmap, false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapPageGroup(KProcessAddress* out_addr, const KPageGroup& pg,
+ KProcessAddress region_start, size_t region_num_pages,
+ KMemoryState state, KMemoryPermission perm) {
+ ASSERT(!this->IsLockedByCurrentThread());
+
+ // Ensure this is a valid map request.
+ const size_t num_pages = pg.GetNumPages();
+ R_UNLESS(this->CanContain(region_start, region_num_pages * PageSize, state),
+ ResultInvalidCurrentMemory);
+ R_UNLESS(num_pages < region_num_pages, ResultOutOfMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Find a random address to map at.
+ KProcessAddress addr = this->FindFreeArea(region_start, region_num_pages, num_pages, PageSize,
+ 0, this->GetNumGuardPages());
+ R_UNLESS(addr != 0, ResultOutOfMemory);
+ ASSERT(this->CanContain(addr, num_pages * PageSize, state));
+ R_ASSERT(this->CheckMemoryState(
+ addr, num_pages * PageSize, KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform mapping operation.
+ const KPageProperties properties = {perm, false, false, DisableMergeAttribute::DisableHead};
+ R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // We successfully mapped the pages.
+ *out_addr = addr;
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapPageGroup(KProcessAddress addr, const KPageGroup& pg, KMemoryState state,
+ KMemoryPermission perm) {
+ ASSERT(!this->IsLockedByCurrentThread());
+
+ // Ensure this is a valid map request.
+ const size_t num_pages = pg.GetNumPages();
+ const size_t size = num_pages * PageSize;
+ R_UNLESS(this->CanContain(addr, size, state), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check if state allows us to map.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), addr, size,
+ KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform mapping operation.
+ const KPageProperties properties = {perm, false, false, DisableMergeAttribute::DisableHead};
+ R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // We successfully mapped the pages.
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnmapPageGroup(KProcessAddress address, const KPageGroup& pg,
+ KMemoryState state) {
+ ASSERT(!this->IsLockedByCurrentThread());
+
+ // Ensure this is a valid unmap request.
+ const size_t num_pages = pg.GetNumPages();
+ const size_t size = num_pages * PageSize;
+ R_UNLESS(this->CanContain(address, size, state), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check if state allows us to unmap.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::All, state, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::None));
+
+ // Check that the page group is valid.
+ R_UNLESS(this->IsValidPageGroup(pg, address, num_pages), ResultInvalidCurrentMemory);
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Perform unmapping operation.
+ const KPageProperties properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), address, num_pages, 0, false, properties,
+ OperationType::Unmap, false));
+
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address,
+ size_t num_pages, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm, KMemoryAttribute attr_mask,
+ KMemoryAttribute attr) {
+ // Ensure that the page group isn't null.
+ ASSERT(out != nullptr);
+
+ // Make sure that the region we're mapping is valid for the table.
+ const size_t size = num_pages * PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check if state allows us to create the group.
+ R_TRY(this->CheckMemoryState(address, size, state_mask | KMemoryState::FlagReferenceCounted,
+ state | KMemoryState::FlagReferenceCounted, perm_mask, perm,
+ attr_mask, attr));
+
+ // Create a new page group for the region.
+ R_TRY(this->MakePageGroup(*out, address, num_pages));
+
+ // Open a new reference to the pages in the group.
+ out->Open();
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::InvalidateProcessDataCache(KProcessAddress address, size_t size) {
+ // Check that the region is in range.
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ R_TRY(this->CheckMemoryStateContiguous(
+ address, size, KMemoryState::FlagReferenceCounted, KMemoryState::FlagReferenceCounted,
+ KMemoryPermission::UserReadWrite, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::Uncached, KMemoryAttribute::None));
+
+ // Get the impl.
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), address);
+ R_UNLESS(traverse_valid, ResultInvalidCurrentMemory);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size = next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ // Iterate.
+ while (tot_size < size) {
+ // Continue the traversal.
+ traverse_valid =
+ impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ R_UNLESS(traverse_valid, ResultInvalidCurrentMemory);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ // Check that the pages are linearly mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Invalidate the block.
+ if (cur_size > 0) {
+ // NOTE: Nintendo does not check the result of invalidation.
+ InvalidateDataCache(GetLinearMappedVirtualPointer(m_kernel, cur_addr), cur_size);
+ }
+
+ // Advance.
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we use the right size for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // Check that the last block is linearly mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Invalidate the last block.
+ if (cur_size > 0) {
+ // NOTE: Nintendo does not check the result of invalidation.
+ InvalidateDataCache(GetLinearMappedVirtualPointer(m_kernel, cur_addr), cur_size);
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size) {
+ // Check pre-condition: this is being called on the current process.
+ ASSERT(this == std::addressof(GetCurrentProcess(m_kernel).GetPageTable().GetBasePageTable()));
+
+ // Check that the region is in range.
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ R_TRY(this->CheckMemoryStateContiguous(
+ address, size, KMemoryState::FlagReferenceCounted, KMemoryState::FlagReferenceCounted,
+ KMemoryPermission::UserReadWrite, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::Uncached, KMemoryAttribute::None));
+
+ // Invalidate the data cache.
+ R_RETURN(InvalidateDataCache(address, size));
+}
+
+Result KPageTableBase::ReadDebugMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size) {
+ // Lightly validate the region is in range.
+ R_UNLESS(this->Contains(src_address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Require that the memory either be user readable or debuggable.
+ const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(
+ src_address, size, KMemoryState::None, KMemoryState::None, KMemoryPermission::UserRead,
+ KMemoryPermission::UserRead, KMemoryAttribute::None, KMemoryAttribute::None));
+ if (!can_read) {
+ const bool can_debug = R_SUCCEEDED(this->CheckMemoryStateContiguous(
+ src_address, size, KMemoryState::FlagCanDebug, KMemoryState::FlagCanDebug,
+ KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+ R_UNLESS(can_debug, ResultInvalidCurrentMemory);
+ }
+
+ // Get the impl.
+ auto& impl = this->GetImpl();
+ auto& dst_memory = GetCurrentMemory(m_system.Kernel());
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), src_address);
+ R_UNLESS(traverse_valid, ResultInvalidCurrentMemory);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size = next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ auto PerformCopy = [&]() -> Result {
+ // Ensure the address is linear mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Copy as much aligned data as we can.
+ if (cur_size >= sizeof(u32)) {
+ const size_t copy_size = Common::AlignDown(cur_size, sizeof(u32));
+ const void* copy_src = GetLinearMappedVirtualPointer(m_kernel, cur_addr);
+ FlushDataCache(copy_src, copy_size);
+ R_UNLESS(dst_memory.WriteBlock(dst_address, copy_src, copy_size), ResultInvalidPointer);
+
+ dst_address += copy_size;
+ cur_addr += copy_size;
+ cur_size -= copy_size;
+ }
+
+ // Copy remaining data.
+ if (cur_size > 0) {
+ const void* copy_src = GetLinearMappedVirtualPointer(m_kernel, cur_addr);
+ FlushDataCache(copy_src, cur_size);
+ R_UNLESS(dst_memory.WriteBlock(dst_address, copy_src, cur_size), ResultInvalidPointer);
+ }
+
+ R_SUCCEED();
+ };
+
+ // Iterate.
+ while (tot_size < size) {
+ // Continue the traversal.
+ traverse_valid =
+ impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ // Perform copy.
+ R_TRY(PerformCopy());
+
+ // Advance.
+ dst_address += cur_size;
+
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we use the right size for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // Perform copy for the last block.
+ R_TRY(PerformCopy());
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::WriteDebugMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size) {
+ // Lightly validate the region is in range.
+ R_UNLESS(this->Contains(dst_address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Require that the memory either be user writable or debuggable.
+ const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(
+ dst_address, size, KMemoryState::None, KMemoryState::None, KMemoryPermission::UserReadWrite,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None, KMemoryAttribute::None));
+ if (!can_read) {
+ const bool can_debug = R_SUCCEEDED(this->CheckMemoryStateContiguous(
+ dst_address, size, KMemoryState::FlagCanDebug, KMemoryState::FlagCanDebug,
+ KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+ R_UNLESS(can_debug, ResultInvalidCurrentMemory);
+ }
+
+ // Get the impl.
+ auto& impl = this->GetImpl();
+ auto& src_memory = GetCurrentMemory(m_system.Kernel());
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), dst_address);
+ R_UNLESS(traverse_valid, ResultInvalidCurrentMemory);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size = next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ auto PerformCopy = [&]() -> Result {
+ // Ensure the address is linear mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Copy as much aligned data as we can.
+ if (cur_size >= sizeof(u32)) {
+ const size_t copy_size = Common::AlignDown(cur_size, sizeof(u32));
+ void* copy_dst = GetLinearMappedVirtualPointer(m_kernel, cur_addr);
+ R_UNLESS(src_memory.ReadBlock(src_address, copy_dst, copy_size),
+ ResultInvalidCurrentMemory);
+
+ StoreDataCache(GetLinearMappedVirtualPointer(m_kernel, cur_addr), copy_size);
+
+ src_address += copy_size;
+ cur_addr += copy_size;
+ cur_size -= copy_size;
+ }
+
+ // Copy remaining data.
+ if (cur_size > 0) {
+ void* copy_dst = GetLinearMappedVirtualPointer(m_kernel, cur_addr);
+ R_UNLESS(src_memory.ReadBlock(src_address, copy_dst, cur_size),
+ ResultInvalidCurrentMemory);
+
+ StoreDataCache(GetLinearMappedVirtualPointer(m_kernel, cur_addr), cur_size);
+ }
+
+ R_SUCCEED();
+ };
+
+ // Iterate.
+ while (tot_size < size) {
+ // Continue the traversal.
+ traverse_valid =
+ impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ // Perform copy.
+ R_TRY(PerformCopy());
+
+ // Advance.
+ src_address += cur_size;
+
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we use the right size for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // Perform copy for the last block.
+ R_TRY(PerformCopy());
+
+ // Invalidate the instruction cache, as this svc allows modifying executable pages.
+ InvalidateInstructionCache(m_system, dst_address, size);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::ReadIoMemoryImpl(KProcessAddress dst_addr, KPhysicalAddress phys_addr,
+ size_t size, KMemoryState state) {
+ // Check pre-conditions.
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Determine the mapping extents.
+ const KPhysicalAddress map_start = Common::AlignDown(GetInteger(phys_addr), PageSize);
+ const KPhysicalAddress map_end = Common::AlignUp(GetInteger(phys_addr) + size, PageSize);
+ const size_t map_size = map_end - map_start;
+
+ // Get the memory reference to write into.
+ auto& dst_memory = GetCurrentMemory(m_kernel);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Temporarily map the io memory.
+ KProcessAddress io_addr;
+ R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size,
+ state, KMemoryPermission::UserRead));
+
+ // Ensure we unmap the io memory when we're done with it.
+ const KPageProperties unmap_properties =
+ KPageProperties{KMemoryPermission::None, false, false, DisableMergeAttribute::None};
+ SCOPE_EXIT({
+ R_ASSERT(this->Operate(updater.GetPageList(), io_addr, map_size / PageSize, 0, false,
+ unmap_properties, OperationType::Unmap, true));
+ });
+
+ // Read the memory.
+ const KProcessAddress read_addr = io_addr + (GetInteger(phys_addr) & (PageSize - 1));
+ dst_memory.CopyBlock(dst_addr, read_addr, size);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::WriteIoMemoryImpl(KPhysicalAddress phys_addr, KProcessAddress src_addr,
+ size_t size, KMemoryState state) {
+ // Check pre-conditions.
+ ASSERT(this->IsLockedByCurrentThread());
+
+ // Determine the mapping extents.
+ const KPhysicalAddress map_start = Common::AlignDown(GetInteger(phys_addr), PageSize);
+ const KPhysicalAddress map_end = Common::AlignUp(GetInteger(phys_addr) + size, PageSize);
+ const size_t map_size = map_end - map_start;
+
+ // Get the memory reference to read from.
+ auto& src_memory = GetCurrentMemory(m_kernel);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Temporarily map the io memory.
+ KProcessAddress io_addr;
+ R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size,
+ state, KMemoryPermission::UserReadWrite));
+
+ // Ensure we unmap the io memory when we're done with it.
+ const KPageProperties unmap_properties =
+ KPageProperties{KMemoryPermission::None, false, false, DisableMergeAttribute::None};
+ SCOPE_EXIT({
+ R_ASSERT(this->Operate(updater.GetPageList(), io_addr, map_size / PageSize, 0, false,
+ unmap_properties, OperationType::Unmap, true));
+ });
+
+ // Write the memory.
+ const KProcessAddress write_addr = io_addr + (GetInteger(phys_addr) & (PageSize - 1));
+ R_UNLESS(src_memory.CopyBlock(write_addr, src_addr, size), ResultInvalidPointer);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::ReadDebugIoMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size, KMemoryState state) {
+ // Lightly validate the range before doing anything else.
+ R_UNLESS(this->Contains(src_address, size), ResultInvalidCurrentMemory);
+
+ // We need to lock both this table, and the current process's table, so set up some aliases.
+ KPageTableBase& src_page_table = *this;
+ KPageTableBase& dst_page_table = GetCurrentProcess(m_kernel).GetPageTable().GetBasePageTable();
+
+ // Acquire the table locks.
+ KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock);
+
+ // Check that the desired range is readable io memory.
+ R_TRY(this->CheckMemoryStateContiguous(src_address, size, KMemoryState::All, state,
+ KMemoryPermission::UserRead, KMemoryPermission::UserRead,
+ KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Read the memory.
+ KProcessAddress dst = dst_address;
+ const KProcessAddress last_address = src_address + size - 1;
+ while (src_address <= last_address) {
+ // Get the current physical address.
+ KPhysicalAddress phys_addr;
+ ASSERT(src_page_table.GetPhysicalAddressLocked(std::addressof(phys_addr), src_address));
+
+ // Determine the current read size.
+ const size_t cur_size =
+ std::min<size_t>(last_address - src_address + 1,
+ Common::AlignDown(GetInteger(src_address) + PageSize, PageSize) -
+ GetInteger(src_address));
+
+ // Read.
+ R_TRY(dst_page_table.ReadIoMemoryImpl(dst, phys_addr, cur_size, state));
+
+ // Advance.
+ src_address += cur_size;
+ dst += cur_size;
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::WriteDebugIoMemory(KProcessAddress dst_address, KProcessAddress src_address,
+ size_t size, KMemoryState state) {
+ // Lightly validate the range before doing anything else.
+ R_UNLESS(this->Contains(dst_address, size), ResultInvalidCurrentMemory);
+
+ // We need to lock both this table, and the current process's table, so set up some aliases.
+ KPageTableBase& src_page_table = *this;
+ KPageTableBase& dst_page_table = GetCurrentProcess(m_kernel).GetPageTable().GetBasePageTable();
+
+ // Acquire the table locks.
+ KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock);
+
+ // Check that the desired range is writable io memory.
+ R_TRY(this->CheckMemoryStateContiguous(
+ dst_address, size, KMemoryState::All, state, KMemoryPermission::UserReadWrite,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Read the memory.
+ KProcessAddress src = src_address;
+ const KProcessAddress last_address = dst_address + size - 1;
+ while (dst_address <= last_address) {
+ // Get the current physical address.
+ KPhysicalAddress phys_addr;
+ ASSERT(src_page_table.GetPhysicalAddressLocked(std::addressof(phys_addr), dst_address));
+
+ // Determine the current read size.
+ const size_t cur_size =
+ std::min<size_t>(last_address - dst_address + 1,
+ Common::AlignDown(GetInteger(dst_address) + PageSize, PageSize) -
+ GetInteger(dst_address));
+
+ // Read.
+ R_TRY(dst_page_table.WriteIoMemoryImpl(phys_addr, src, cur_size, state));
+
+ // Advance.
+ dst_address += cur_size;
+ src += cur_size;
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address,
+ size_t size, KMemoryPermission perm,
+ bool is_aligned, bool check_heap) {
+ // Lightly validate the range before doing anything else.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ const KMemoryState test_state =
+ (is_aligned ? KMemoryState::FlagCanAlignedDeviceMap : KMemoryState::FlagCanDeviceMap) |
+ (check_heap ? KMemoryState::FlagReferenceCounted : KMemoryState::None);
+ size_t num_allocator_blocks;
+ KMemoryState old_state;
+ R_TRY(this->CheckMemoryState(std::addressof(old_state), nullptr, nullptr,
+ std::addressof(num_allocator_blocks), address, size, test_state,
+ test_state, perm, perm,
+ KMemoryAttribute::IpcLocked | KMemoryAttribute::Locked,
+ KMemoryAttribute::None, KMemoryAttribute::DeviceShared));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Update the memory blocks.
+ m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages,
+ &KMemoryBlock::ShareToDevice, KMemoryPermission::None);
+
+ // Set whether the locked memory was io.
+ *out_is_io =
+ static_cast<Svc::MemoryState>(old_state & KMemoryState::Mask) == Svc::MemoryState::Io;
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size,
+ bool check_heap) {
+ // Lightly validate the range before doing anything else.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ const KMemoryState test_state =
+ KMemoryState::FlagCanDeviceMap |
+ (check_heap ? KMemoryState::FlagReferenceCounted : KMemoryState::None);
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryStateContiguous(
+ std::addressof(num_allocator_blocks), address, size, test_state, test_state,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Update the memory blocks.
+ const KMemoryBlockManager::MemoryBlockLockFunction lock_func =
+ m_enable_device_address_space_merge
+ ? &KMemoryBlock::UpdateDeviceDisableMergeStateForShare
+ : &KMemoryBlock::UpdateDeviceDisableMergeStateForShareRight;
+ m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages, lock_func,
+ KMemoryPermission::None);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) {
+ // Lightly validate the range before doing anything else.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryStateContiguous(
+ std::addressof(num_allocator_blocks), address, size, KMemoryState::FlagCanDeviceMap,
+ KMemoryState::FlagCanDeviceMap, KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Update the memory blocks.
+ m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages,
+ &KMemoryBlock::UnshareToDevice, KMemoryPermission::None);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size) {
+ // Lightly validate the range before doing anything else.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check memory state.
+ size_t allocator_num_blocks = 0;
+ R_TRY(this->CheckMemoryStateContiguous(
+ std::addressof(allocator_num_blocks), address, size, KMemoryState::FlagCanDeviceMap,
+ KMemoryState::FlagCanDeviceMap, KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
+
+ // Create an update allocator for the region.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, allocator_num_blocks);
+ R_TRY(allocator_result);
+
+ // Update the memory blocks.
+ m_memory_block_manager.UpdateLock(
+ std::addressof(allocator), address, num_pages,
+ m_enable_device_address_space_merge
+ ? &KMemoryBlock::UpdateDeviceDisableMergeStateForUnshare
+ : &KMemoryBlock::UpdateDeviceDisableMergeStateForUnshareRight,
+ KMemoryPermission::None);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::OpenMemoryRangeForMapDeviceAddressSpace(KPageTableBase::MemoryRange* out,
+ KProcessAddress address, size_t size,
+ KMemoryPermission perm,
+ bool is_aligned) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Get the range.
+ const KMemoryState test_state =
+ (is_aligned ? KMemoryState::FlagCanAlignedDeviceMap : KMemoryState::FlagCanDeviceMap);
+ R_TRY(this->GetContiguousMemoryRangeWithState(
+ out, address, size, test_state, test_state, perm, perm,
+ KMemoryAttribute::IpcLocked | KMemoryAttribute::Locked, KMemoryAttribute::None));
+
+ // We got the range, so open it.
+ out->Open();
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::OpenMemoryRangeForUnmapDeviceAddressSpace(MemoryRange* out,
+ KProcessAddress address,
+ size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Get the range.
+ R_TRY(this->GetContiguousMemoryRangeWithState(
+ out, address, size, KMemoryState::FlagCanDeviceMap, KMemoryState::FlagCanDeviceMap,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
+
+ // We got the range, so open it.
+ out->Open();
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address,
+ size_t size) {
+ R_RETURN(this->LockMemoryAndOpen(
+ nullptr, out, address, size, KMemoryState::FlagCanIpcUserBuffer,
+ KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::All,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None,
+ static_cast<KMemoryPermission>(KMemoryPermission::NotMapped |
+ KMemoryPermission::KernelReadWrite),
+ KMemoryAttribute::Locked));
+}
+
+Result KPageTableBase::UnlockForIpcUserBuffer(KProcessAddress address, size_t size) {
+ R_RETURN(this->UnlockMemory(address, size, KMemoryState::FlagCanIpcUserBuffer,
+ KMemoryState::FlagCanIpcUserBuffer, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::Locked, nullptr));
+}
+
+Result KPageTableBase::LockForTransferMemory(KPageGroup* out, KProcessAddress address, size_t size,
+ KMemoryPermission perm) {
+ R_RETURN(this->LockMemoryAndOpen(out, nullptr, address, size, KMemoryState::FlagCanTransfer,
+ KMemoryState::FlagCanTransfer, KMemoryPermission::All,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
+ KMemoryAttribute::None, perm, KMemoryAttribute::Locked));
+}
+
+Result KPageTableBase::UnlockForTransferMemory(KProcessAddress address, size_t size,
+ const KPageGroup& pg) {
+ R_RETURN(this->UnlockMemory(address, size, KMemoryState::FlagCanTransfer,
+ KMemoryState::FlagCanTransfer, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::Locked, std::addressof(pg)));
+}
+
+Result KPageTableBase::LockForCodeMemory(KPageGroup* out, KProcessAddress address, size_t size) {
+ R_RETURN(this->LockMemoryAndOpen(
+ out, nullptr, address, size, KMemoryState::FlagCanCodeMemory,
+ KMemoryState::FlagCanCodeMemory, KMemoryPermission::All, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::All, KMemoryAttribute::None,
+ static_cast<KMemoryPermission>(KMemoryPermission::NotMapped |
+ KMemoryPermission::KernelReadWrite),
+ KMemoryAttribute::Locked));
+}
+
+Result KPageTableBase::UnlockForCodeMemory(KProcessAddress address, size_t size,
+ const KPageGroup& pg) {
+ R_RETURN(this->UnlockMemory(address, size, KMemoryState::FlagCanCodeMemory,
+ KMemoryState::FlagCanCodeMemory, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::Locked, std::addressof(pg)));
+}
+
+Result KPageTableBase::OpenMemoryRangeForProcessCacheOperation(MemoryRange* out,
+ KProcessAddress address,
+ size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Get the range.
+ R_TRY(this->GetContiguousMemoryRangeWithState(
+ out, address, size, KMemoryState::FlagReferenceCounted, KMemoryState::FlagReferenceCounted,
+ KMemoryPermission::UserRead, KMemoryPermission::UserRead, KMemoryAttribute::Uncached,
+ KMemoryAttribute::None));
+
+ // We got the range, so open it.
+ out->Open();
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CopyMemoryFromLinearToUser(
+ KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, KMemoryState src_state_mask,
+ KMemoryState src_state, KMemoryPermission src_test_perm, KMemoryAttribute src_attr_mask,
+ KMemoryAttribute src_attr) {
+ // Lightly validate the range before doing anything else.
+ R_UNLESS(this->Contains(src_addr, size), ResultInvalidCurrentMemory);
+
+ // Get the destination memory reference.
+ auto& dst_memory = GetCurrentMemory(m_kernel);
+
+ // Copy the memory.
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check memory state.
+ R_TRY(this->CheckMemoryStateContiguous(
+ src_addr, size, src_state_mask, src_state, src_test_perm, src_test_perm,
+ src_attr_mask | KMemoryAttribute::Uncached, src_attr));
+
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), src_addr);
+ ASSERT(traverse_valid);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size =
+ next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ auto PerformCopy = [&]() -> Result {
+ // Ensure the address is linear mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Copy as much aligned data as we can.
+ if (cur_size >= sizeof(u32)) {
+ const size_t copy_size = Common::AlignDown(cur_size, sizeof(u32));
+ R_UNLESS(dst_memory.WriteBlock(dst_addr,
+ GetLinearMappedVirtualPointer(m_kernel, cur_addr),
+ copy_size),
+ ResultInvalidCurrentMemory);
+
+ dst_addr += copy_size;
+ cur_addr += copy_size;
+ cur_size -= copy_size;
+ }
+
+ // Copy remaining data.
+ if (cur_size > 0) {
+ R_UNLESS(dst_memory.WriteBlock(
+ dst_addr, GetLinearMappedVirtualPointer(m_kernel, cur_addr), cur_size),
+ ResultInvalidCurrentMemory);
+ }
+
+ R_SUCCEED();
+ };
+
+ // Iterate.
+ while (tot_size < size) {
+ // Continue the traversal.
+ traverse_valid =
+ impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ // Perform copy.
+ R_TRY(PerformCopy());
+
+ // Advance.
+ dst_addr += cur_size;
+
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we use the right size for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // Perform copy for the last block.
+ R_TRY(PerformCopy());
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CopyMemoryFromLinearToKernel(
+ void* buffer, size_t size, KProcessAddress src_addr, KMemoryState src_state_mask,
+ KMemoryState src_state, KMemoryPermission src_test_perm, KMemoryAttribute src_attr_mask,
+ KMemoryAttribute src_attr) {
+ // Lightly validate the range before doing anything else.
+ R_UNLESS(this->Contains(src_addr, size), ResultInvalidCurrentMemory);
+
+ // Copy the memory.
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check memory state.
+ R_TRY(this->CheckMemoryStateContiguous(
+ src_addr, size, src_state_mask, src_state, src_test_perm, src_test_perm,
+ src_attr_mask | KMemoryAttribute::Uncached, src_attr));
+
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), src_addr);
+ ASSERT(traverse_valid);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size =
+ next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ auto PerformCopy = [&]() -> Result {
+ // Ensure the address is linear mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Copy the data.
+ std::memcpy(buffer, GetLinearMappedVirtualPointer(m_kernel, cur_addr), cur_size);
+
+ R_SUCCEED();
+ };
+
+ // Iterate.
+ while (tot_size < size) {
+ // Continue the traversal.
+ traverse_valid =
+ impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ // Perform copy.
+ R_TRY(PerformCopy());
+
+ // Advance.
+ buffer = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(buffer) + cur_size);
+
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we use the right size for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // Perform copy for the last block.
+ R_TRY(PerformCopy());
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CopyMemoryFromUserToLinear(
+ KProcessAddress dst_addr, size_t size, KMemoryState dst_state_mask, KMemoryState dst_state,
+ KMemoryPermission dst_test_perm, KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr,
+ KProcessAddress src_addr) {
+ // Lightly validate the range before doing anything else.
+ R_UNLESS(this->Contains(dst_addr, size), ResultInvalidCurrentMemory);
+
+ // Get the source memory reference.
+ auto& src_memory = GetCurrentMemory(m_kernel);
+
+ // Copy the memory.
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check memory state.
+ R_TRY(this->CheckMemoryStateContiguous(
+ dst_addr, size, dst_state_mask, dst_state, dst_test_perm, dst_test_perm,
+ dst_attr_mask | KMemoryAttribute::Uncached, dst_attr));
+
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), dst_addr);
+ ASSERT(traverse_valid);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size =
+ next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ auto PerformCopy = [&]() -> Result {
+ // Ensure the address is linear mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Copy as much aligned data as we can.
+ if (cur_size >= sizeof(u32)) {
+ const size_t copy_size = Common::AlignDown(cur_size, sizeof(u32));
+ R_UNLESS(src_memory.ReadBlock(src_addr,
+ GetLinearMappedVirtualPointer(m_kernel, cur_addr),
+ copy_size),
+ ResultInvalidCurrentMemory);
+ src_addr += copy_size;
+ cur_addr += copy_size;
+ cur_size -= copy_size;
+ }
+
+ // Copy remaining data.
+ if (cur_size > 0) {
+ R_UNLESS(src_memory.ReadBlock(
+ src_addr, GetLinearMappedVirtualPointer(m_kernel, cur_addr), cur_size),
+ ResultInvalidCurrentMemory);
+ }
+
+ R_SUCCEED();
+ };
+
+ // Iterate.
+ while (tot_size < size) {
+ // Continue the traversal.
+ traverse_valid =
+ impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ // Perform copy.
+ R_TRY(PerformCopy());
+
+ // Advance.
+ src_addr += cur_size;
+
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we use the right size for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // Perform copy for the last block.
+ R_TRY(PerformCopy());
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CopyMemoryFromKernelToLinear(KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask,
+ KMemoryState dst_state,
+ KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask,
+ KMemoryAttribute dst_attr, void* buffer) {
+ // Lightly validate the range before doing anything else.
+ R_UNLESS(this->Contains(dst_addr, size), ResultInvalidCurrentMemory);
+
+ // Copy the memory.
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check memory state.
+ R_TRY(this->CheckMemoryStateContiguous(
+ dst_addr, size, dst_state_mask, dst_state, dst_test_perm, dst_test_perm,
+ dst_attr_mask | KMemoryAttribute::Uncached, dst_attr));
+
+ auto& impl = this->GetImpl();
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid =
+ impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), dst_addr);
+ ASSERT(traverse_valid);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_addr = next_entry.phys_addr;
+ size_t cur_size =
+ next_entry.block_size - (GetInteger(cur_addr) & (next_entry.block_size - 1));
+ size_t tot_size = cur_size;
+
+ auto PerformCopy = [&]() -> Result {
+ // Ensure the address is linear mapped.
+ R_UNLESS(IsLinearMappedPhysicalAddress(cur_addr), ResultInvalidCurrentMemory);
+
+ // Copy the data.
+ std::memcpy(GetLinearMappedVirtualPointer(m_kernel, cur_addr), buffer, cur_size);
+
+ R_SUCCEED();
+ };
+
+ // Iterate.
+ while (tot_size < size) {
+ // Continue the traversal.
+ traverse_valid =
+ impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ if (next_entry.phys_addr != (cur_addr + cur_size)) {
+ // Perform copy.
+ R_TRY(PerformCopy());
+
+ // Advance.
+ buffer = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(buffer) + cur_size);
+
+ cur_addr = next_entry.phys_addr;
+ cur_size = next_entry.block_size;
+ } else {
+ cur_size += next_entry.block_size;
+ }
+
+ tot_size += next_entry.block_size;
+ }
+
+ // Ensure we use the right size for the last block.
+ if (tot_size > size) {
+ cur_size -= (tot_size - size);
+ }
+
+ // Perform copy for the last block.
+ R_TRY(PerformCopy());
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CopyMemoryFromHeapToHeap(
+ KPageTableBase& dst_page_table, KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state, KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr, KProcessAddress src_addr,
+ KMemoryState src_state_mask, KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr) {
+ // For convenience, alias this.
+ KPageTableBase& src_page_table = *this;
+
+ // Lightly validate the ranges before doing anything else.
+ R_UNLESS(src_page_table.Contains(src_addr, size), ResultInvalidCurrentMemory);
+ R_UNLESS(dst_page_table.Contains(dst_addr, size), ResultInvalidCurrentMemory);
+
+ // Copy the memory.
+ {
+ // Acquire the table locks.
+ KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock);
+
+ // Check memory state.
+ R_TRY(src_page_table.CheckMemoryStateContiguous(
+ src_addr, size, src_state_mask, src_state, src_test_perm, src_test_perm,
+ src_attr_mask | KMemoryAttribute::Uncached, src_attr));
+ R_TRY(dst_page_table.CheckMemoryStateContiguous(
+ dst_addr, size, dst_state_mask, dst_state, dst_test_perm, dst_test_perm,
+ dst_attr_mask | KMemoryAttribute::Uncached, dst_attr));
+
+ // Get implementations.
+ auto& src_impl = src_page_table.GetImpl();
+ auto& dst_impl = dst_page_table.GetImpl();
+
+ // Prepare for traversal.
+ TraversalContext src_context;
+ TraversalContext dst_context;
+ TraversalEntry src_next_entry;
+ TraversalEntry dst_next_entry;
+ bool traverse_valid;
+
+ // Begin traversal.
+ traverse_valid = src_impl.BeginTraversal(std::addressof(src_next_entry),
+ std::addressof(src_context), src_addr);
+ ASSERT(traverse_valid);
+ traverse_valid = dst_impl.BeginTraversal(std::addressof(dst_next_entry),
+ std::addressof(dst_context), dst_addr);
+ ASSERT(traverse_valid);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_src_block_addr = src_next_entry.phys_addr;
+ KPhysicalAddress cur_dst_block_addr = dst_next_entry.phys_addr;
+ size_t cur_src_size = src_next_entry.block_size -
+ (GetInteger(cur_src_block_addr) & (src_next_entry.block_size - 1));
+ size_t cur_dst_size = dst_next_entry.block_size -
+ (GetInteger(cur_dst_block_addr) & (dst_next_entry.block_size - 1));
+
+ // Adjust the initial block sizes.
+ src_next_entry.block_size = cur_src_size;
+ dst_next_entry.block_size = cur_dst_size;
+
+ // Before we get any crazier, succeed if there's nothing to do.
+ R_SUCCEED_IF(size == 0);
+
+ // We're going to manage dual traversal via an offset against the total size.
+ KPhysicalAddress cur_src_addr = cur_src_block_addr;
+ KPhysicalAddress cur_dst_addr = cur_dst_block_addr;
+ size_t cur_min_size = std::min<size_t>(cur_src_size, cur_dst_size);
+
+ // Iterate.
+ size_t ofs = 0;
+ while (ofs < size) {
+ // Determine how much we can copy this iteration.
+ const size_t cur_copy_size = std::min<size_t>(cur_min_size, size - ofs);
+
+ // If we need to advance the traversals, do so.
+ bool updated_src = false, updated_dst = false, skip_copy = false;
+ if (ofs + cur_copy_size != size) {
+ if (cur_src_addr + cur_min_size == cur_src_block_addr + cur_src_size) {
+ // Continue the src traversal.
+ traverse_valid = src_impl.ContinueTraversal(std::addressof(src_next_entry),
+ std::addressof(src_context));
+ ASSERT(traverse_valid);
+
+ // Update source.
+ updated_src = cur_src_addr + cur_min_size != src_next_entry.phys_addr;
+ }
+
+ if (cur_dst_addr + cur_min_size ==
+ dst_next_entry.phys_addr + dst_next_entry.block_size) {
+ // Continue the dst traversal.
+ traverse_valid = dst_impl.ContinueTraversal(std::addressof(dst_next_entry),
+ std::addressof(dst_context));
+ ASSERT(traverse_valid);
+
+ // Update destination.
+ updated_dst = cur_dst_addr + cur_min_size != dst_next_entry.phys_addr;
+ }
+
+ // If we didn't update either of source/destination, skip the copy this iteration.
+ if (!updated_src && !updated_dst) {
+ skip_copy = true;
+
+ // Update the source block address.
+ cur_src_block_addr = src_next_entry.phys_addr;
+ }
+ }
+
+ // Do the copy, unless we're skipping it.
+ if (!skip_copy) {
+ // We need both ends of the copy to be heap blocks.
+ R_UNLESS(IsHeapPhysicalAddress(cur_src_addr), ResultInvalidCurrentMemory);
+ R_UNLESS(IsHeapPhysicalAddress(cur_dst_addr), ResultInvalidCurrentMemory);
+
+ // Copy the data.
+ std::memcpy(GetHeapVirtualPointer(m_kernel, cur_dst_addr),
+ GetHeapVirtualPointer(m_kernel, cur_src_addr), cur_copy_size);
+
+ // Update.
+ cur_src_block_addr = src_next_entry.phys_addr;
+ cur_src_addr = updated_src ? cur_src_block_addr : cur_src_addr + cur_copy_size;
+ cur_dst_block_addr = dst_next_entry.phys_addr;
+ cur_dst_addr = updated_dst ? cur_dst_block_addr : cur_dst_addr + cur_copy_size;
+
+ // Advance offset.
+ ofs += cur_copy_size;
+ }
+
+ // Update min size.
+ cur_src_size = src_next_entry.block_size;
+ cur_dst_size = dst_next_entry.block_size;
+ cur_min_size = std::min<size_t>(cur_src_block_addr - cur_src_addr + cur_src_size,
+ cur_dst_block_addr - cur_dst_addr + cur_dst_size);
+ }
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CopyMemoryFromHeapToHeapWithoutCheckDestination(
+ KPageTableBase& dst_page_table, KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state, KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr, KProcessAddress src_addr,
+ KMemoryState src_state_mask, KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr) {
+ // For convenience, alias this.
+ KPageTableBase& src_page_table = *this;
+
+ // Lightly validate the ranges before doing anything else.
+ R_UNLESS(src_page_table.Contains(src_addr, size), ResultInvalidCurrentMemory);
+ R_UNLESS(dst_page_table.Contains(dst_addr, size), ResultInvalidCurrentMemory);
+
+ // Copy the memory.
+ {
+ // Acquire the table locks.
+ KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock);
+
+ // Check memory state for source.
+ R_TRY(src_page_table.CheckMemoryStateContiguous(
+ src_addr, size, src_state_mask, src_state, src_test_perm, src_test_perm,
+ src_attr_mask | KMemoryAttribute::Uncached, src_attr));
+
+ // Destination state is intentionally unchecked.
+
+ // Get implementations.
+ auto& src_impl = src_page_table.GetImpl();
+ auto& dst_impl = dst_page_table.GetImpl();
+
+ // Prepare for traversal.
+ TraversalContext src_context;
+ TraversalContext dst_context;
+ TraversalEntry src_next_entry;
+ TraversalEntry dst_next_entry;
+ bool traverse_valid;
+
+ // Begin traversal.
+ traverse_valid = src_impl.BeginTraversal(std::addressof(src_next_entry),
+ std::addressof(src_context), src_addr);
+ ASSERT(traverse_valid);
+ traverse_valid = dst_impl.BeginTraversal(std::addressof(dst_next_entry),
+ std::addressof(dst_context), dst_addr);
+ ASSERT(traverse_valid);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_src_block_addr = src_next_entry.phys_addr;
+ KPhysicalAddress cur_dst_block_addr = dst_next_entry.phys_addr;
+ size_t cur_src_size = src_next_entry.block_size -
+ (GetInteger(cur_src_block_addr) & (src_next_entry.block_size - 1));
+ size_t cur_dst_size = dst_next_entry.block_size -
+ (GetInteger(cur_dst_block_addr) & (dst_next_entry.block_size - 1));
+
+ // Adjust the initial block sizes.
+ src_next_entry.block_size = cur_src_size;
+ dst_next_entry.block_size = cur_dst_size;
+
+ // Before we get any crazier, succeed if there's nothing to do.
+ R_SUCCEED_IF(size == 0);
+
+ // We're going to manage dual traversal via an offset against the total size.
+ KPhysicalAddress cur_src_addr = cur_src_block_addr;
+ KPhysicalAddress cur_dst_addr = cur_dst_block_addr;
+ size_t cur_min_size = std::min<size_t>(cur_src_size, cur_dst_size);
+
+ // Iterate.
+ size_t ofs = 0;
+ while (ofs < size) {
+ // Determine how much we can copy this iteration.
+ const size_t cur_copy_size = std::min<size_t>(cur_min_size, size - ofs);
+
+ // If we need to advance the traversals, do so.
+ bool updated_src = false, updated_dst = false, skip_copy = false;
+ if (ofs + cur_copy_size != size) {
+ if (cur_src_addr + cur_min_size == cur_src_block_addr + cur_src_size) {
+ // Continue the src traversal.
+ traverse_valid = src_impl.ContinueTraversal(std::addressof(src_next_entry),
+ std::addressof(src_context));
+ ASSERT(traverse_valid);
+
+ // Update source.
+ updated_src = cur_src_addr + cur_min_size != src_next_entry.phys_addr;
+ }
+
+ if (cur_dst_addr + cur_min_size ==
+ dst_next_entry.phys_addr + dst_next_entry.block_size) {
+ // Continue the dst traversal.
+ traverse_valid = dst_impl.ContinueTraversal(std::addressof(dst_next_entry),
+ std::addressof(dst_context));
+ ASSERT(traverse_valid);
+
+ // Update destination.
+ updated_dst = cur_dst_addr + cur_min_size != dst_next_entry.phys_addr;
+ }
+
+ // If we didn't update either of source/destination, skip the copy this iteration.
+ if (!updated_src && !updated_dst) {
+ skip_copy = true;
+
+ // Update the source block address.
+ cur_src_block_addr = src_next_entry.phys_addr;
+ }
+ }
+
+ // Do the copy, unless we're skipping it.
+ if (!skip_copy) {
+ // We need both ends of the copy to be heap blocks.
+ R_UNLESS(IsHeapPhysicalAddress(cur_src_addr), ResultInvalidCurrentMemory);
+ R_UNLESS(IsHeapPhysicalAddress(cur_dst_addr), ResultInvalidCurrentMemory);
+
+ // Copy the data.
+ std::memcpy(GetHeapVirtualPointer(m_kernel, cur_dst_addr),
+ GetHeapVirtualPointer(m_kernel, cur_src_addr), cur_copy_size);
+
+ // Update.
+ cur_src_block_addr = src_next_entry.phys_addr;
+ cur_src_addr = updated_src ? cur_src_block_addr : cur_src_addr + cur_copy_size;
+ cur_dst_block_addr = dst_next_entry.phys_addr;
+ cur_dst_addr = updated_dst ? cur_dst_block_addr : cur_dst_addr + cur_copy_size;
+
+ // Advance offset.
+ ofs += cur_copy_size;
+ }
+
+ // Update min size.
+ cur_src_size = src_next_entry.block_size;
+ cur_dst_size = dst_next_entry.block_size;
+ cur_min_size = std::min<size_t>(cur_src_block_addr - cur_src_addr + cur_src_size,
+ cur_dst_block_addr - cur_dst_addr + cur_dst_size);
+ }
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed,
+ KProcessAddress address, size_t size,
+ KMemoryPermission test_perm, KMemoryState dst_state) {
+ // Validate pre-conditions.
+ ASSERT(this->IsLockedByCurrentThread());
+ ASSERT(test_perm == KMemoryPermission::UserReadWrite ||
+ test_perm == KMemoryPermission::UserRead);
+
+ // Check that the address is in range.
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Get the source permission.
+ const auto src_perm = static_cast<KMemoryPermission>(
+ (test_perm == KMemoryPermission::UserReadWrite)
+ ? KMemoryPermission::KernelReadWrite | KMemoryPermission::NotMapped
+ : KMemoryPermission::UserRead);
+
+ // Get aligned extents.
+ const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(address), PageSize);
+ const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(address) + size, PageSize);
+ const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(address), PageSize);
+ const KProcessAddress mapping_src_end = Common::AlignDown(GetInteger(address) + size, PageSize);
+
+ const auto aligned_src_last = GetInteger(aligned_src_end) - 1;
+ const auto mapping_src_last = GetInteger(mapping_src_end) - 1;
+
+ // Get the test state and attribute mask.
+ KMemoryState test_state;
+ KMemoryAttribute test_attr_mask;
+ switch (dst_state) {
+ case KMemoryState::Ipc:
+ test_state = KMemoryState::FlagCanUseIpc;
+ test_attr_mask =
+ KMemoryAttribute::Uncached | KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked;
+ break;
+ case KMemoryState::NonSecureIpc:
+ test_state = KMemoryState::FlagCanUseNonSecureIpc;
+ test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
+ break;
+ case KMemoryState::NonDeviceIpc:
+ test_state = KMemoryState::FlagCanUseNonDeviceIpc;
+ test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
+ break;
+ default:
+ R_THROW(ResultInvalidCombination);
+ }
+
+ // Ensure that on failure, we roll back appropriately.
+ size_t mapped_size = 0;
+ ON_RESULT_FAILURE {
+ if (mapped_size > 0) {
+ this->CleanupForIpcClientOnServerSetupFailure(page_list, mapping_src_start, mapped_size,
+ src_perm);
+ }
+ };
+
+ size_t blocks_needed = 0;
+
+ // Iterate, mapping as needed.
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(aligned_src_start);
+ while (true) {
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // Validate the current block.
+ R_TRY(this->CheckMemoryState(info, test_state, test_state, test_perm, test_perm,
+ test_attr_mask, KMemoryAttribute::None));
+
+ if (mapping_src_start < mapping_src_end &&
+ GetInteger(mapping_src_start) < info.GetEndAddress() &&
+ info.GetAddress() < GetInteger(mapping_src_end)) {
+ const auto cur_start = info.GetAddress() >= GetInteger(mapping_src_start)
+ ? info.GetAddress()
+ : GetInteger(mapping_src_start);
+ const auto cur_end = mapping_src_last >= info.GetLastAddress()
+ ? info.GetEndAddress()
+ : GetInteger(mapping_src_end);
+ const size_t cur_size = cur_end - cur_start;
+
+ if (info.GetAddress() < GetInteger(mapping_src_start)) {
+ ++blocks_needed;
+ }
+ if (mapping_src_last < info.GetLastAddress()) {
+ ++blocks_needed;
+ }
+
+ // Set the permissions on the block, if we need to.
+ if ((info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != src_perm) {
+ const DisableMergeAttribute head_body_attr =
+ (GetInteger(mapping_src_start) >= info.GetAddress())
+ ? DisableMergeAttribute::DisableHeadAndBody
+ : DisableMergeAttribute::None;
+ const DisableMergeAttribute tail_attr = (cur_end == GetInteger(mapping_src_end))
+ ? DisableMergeAttribute::DisableTail
+ : DisableMergeAttribute::None;
+ const KPageProperties properties = {
+ src_perm, false, false,
+ static_cast<DisableMergeAttribute>(head_body_attr | tail_attr)};
+ R_TRY(this->Operate(page_list, cur_start, cur_size / PageSize, 0, false, properties,
+ OperationType::ChangePermissions, false));
+ }
+
+ // Note that we mapped this part.
+ mapped_size += cur_size;
+ }
+
+ // If the block is at the end, we're done.
+ if (aligned_src_last <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ ++it;
+ ASSERT(it != m_memory_block_manager.end());
+ }
+
+ if (out_blocks_needed != nullptr) {
+ ASSERT(blocks_needed <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
+ *out_blocks_needed = blocks_needed;
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::SetupForIpcServer(KProcessAddress* out_addr, size_t size,
+ KProcessAddress src_addr, KMemoryPermission test_perm,
+ KMemoryState dst_state, KPageTableBase& src_page_table,
+ bool send) {
+ ASSERT(this->IsLockedByCurrentThread());
+ ASSERT(src_page_table.IsLockedByCurrentThread());
+
+ // Check that we can theoretically map.
+ const KProcessAddress region_start = m_alias_region_start;
+ const size_t region_size = m_alias_region_end - m_alias_region_start;
+ R_UNLESS(size < region_size, ResultOutOfAddressSpace);
+
+ // Get aligned source extents.
+ const KProcessAddress src_start = src_addr;
+ const KProcessAddress src_end = src_addr + size;
+ const KProcessAddress aligned_src_start = Common::AlignDown(GetInteger(src_start), PageSize);
+ const KProcessAddress aligned_src_end = Common::AlignUp(GetInteger(src_start) + size, PageSize);
+ const KProcessAddress mapping_src_start = Common::AlignUp(GetInteger(src_start), PageSize);
+ const KProcessAddress mapping_src_end =
+ Common::AlignDown(GetInteger(src_start) + size, PageSize);
+ const size_t aligned_src_size = aligned_src_end - aligned_src_start;
+ const size_t mapping_src_size =
+ (mapping_src_start < mapping_src_end) ? (mapping_src_end - mapping_src_start) : 0;
+
+ // Select a random address to map at.
+ KProcessAddress dst_addr = 0;
+ {
+ const size_t alignment = 4_KiB;
+ const size_t offset = GetInteger(aligned_src_start) & (alignment - 1);
+
+ dst_addr =
+ this->FindFreeArea(region_start, region_size / PageSize, aligned_src_size / PageSize,
+ alignment, offset, this->GetNumGuardPages());
+ R_UNLESS(dst_addr != 0, ResultOutOfAddressSpace);
+ }
+
+ // Check that we can perform the operation we're about to perform.
+ ASSERT(this->CanContain(dst_addr, aligned_src_size, dst_state));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Reserve space for any partial pages we allocate.
+ const size_t unmapped_size = aligned_src_size - mapping_src_size;
+ KScopedResourceReservation memory_reservation(
+ m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, unmapped_size);
+ R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
+
+ // Ensure that we manage page references correctly.
+ KPhysicalAddress start_partial_page = 0;
+ KPhysicalAddress end_partial_page = 0;
+ KProcessAddress cur_mapped_addr = dst_addr;
+
+ // If the partial pages are mapped, an extra reference will have been opened. Otherwise, they'll
+ // free on scope exit.
+ SCOPE_EXIT({
+ if (start_partial_page != 0) {
+ m_kernel.MemoryManager().Close(start_partial_page, 1);
+ }
+ if (end_partial_page != 0) {
+ m_kernel.MemoryManager().Close(end_partial_page, 1);
+ }
+ });
+
+ ON_RESULT_FAILURE {
+ if (cur_mapped_addr != dst_addr) {
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_ASSERT(this->Operate(updater.GetPageList(), dst_addr,
+ (cur_mapped_addr - dst_addr) / PageSize, 0, false,
+ unmap_properties, OperationType::Unmap, true));
+ }
+ };
+
+ // Allocate the start page as needed.
+ if (aligned_src_start < mapping_src_start) {
+ start_partial_page =
+ m_kernel.MemoryManager().AllocateAndOpenContinuous(1, 1, m_allocate_option);
+ R_UNLESS(start_partial_page != 0, ResultOutOfMemory);
+ }
+
+ // Allocate the end page as needed.
+ if (mapping_src_end < aligned_src_end &&
+ (aligned_src_start < mapping_src_end || aligned_src_start == mapping_src_start)) {
+ end_partial_page =
+ m_kernel.MemoryManager().AllocateAndOpenContinuous(1, 1, m_allocate_option);
+ R_UNLESS(end_partial_page != 0, ResultOutOfMemory);
+ }
+
+ // Get the implementation.
+ auto& src_impl = src_page_table.GetImpl();
+
+ // Get the fill value for partial pages.
+ const auto fill_val = m_ipc_fill_value;
+
+ // Begin traversal.
+ TraversalContext context;
+ TraversalEntry next_entry;
+ bool traverse_valid = src_impl.BeginTraversal(std::addressof(next_entry),
+ std::addressof(context), aligned_src_start);
+ ASSERT(traverse_valid);
+
+ // Prepare tracking variables.
+ KPhysicalAddress cur_block_addr = next_entry.phys_addr;
+ size_t cur_block_size =
+ next_entry.block_size - (GetInteger(cur_block_addr) & (next_entry.block_size - 1));
+ size_t tot_block_size = cur_block_size;
+
+ // Map the start page, if we have one.
+ if (start_partial_page != 0) {
+ // Ensure the page holds correct data.
+ u8* const start_partial_virt = GetHeapVirtualPointer(m_kernel, start_partial_page);
+ if (send) {
+ const size_t partial_offset = src_start - aligned_src_start;
+ size_t copy_size, clear_size;
+ if (src_end < mapping_src_start) {
+ copy_size = size;
+ clear_size = mapping_src_start - src_end;
+ } else {
+ copy_size = mapping_src_start - src_start;
+ clear_size = 0;
+ }
+
+ std::memset(start_partial_virt, fill_val, partial_offset);
+ std::memcpy(start_partial_virt + partial_offset,
+ GetHeapVirtualPointer(m_kernel, cur_block_addr) + partial_offset,
+ copy_size);
+ if (clear_size > 0) {
+ std::memset(start_partial_virt + partial_offset + copy_size, fill_val, clear_size);
+ }
+ } else {
+ std::memset(start_partial_virt, fill_val, PageSize);
+ }
+
+ // Map the page.
+ const KPageProperties start_map_properties = {test_perm, false, false,
+ DisableMergeAttribute::DisableHead};
+ R_TRY(this->Operate(updater.GetPageList(), cur_mapped_addr, 1, start_partial_page, true,
+ start_map_properties, OperationType::Map, false));
+
+ // Update tracking extents.
+ cur_mapped_addr += PageSize;
+ cur_block_addr += PageSize;
+ cur_block_size -= PageSize;
+
+ // If the block's size was one page, we may need to continue traversal.
+ if (cur_block_size == 0 && aligned_src_size > PageSize) {
+ traverse_valid =
+ src_impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ cur_block_addr = next_entry.phys_addr;
+ cur_block_size = next_entry.block_size;
+ tot_block_size += next_entry.block_size;
+ }
+ }
+
+ // Map the remaining pages.
+ while (aligned_src_start + tot_block_size < mapping_src_end) {
+ // Continue the traversal.
+ traverse_valid =
+ src_impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ // Process the block.
+ if (next_entry.phys_addr != cur_block_addr + cur_block_size) {
+ // Map the block we've been processing so far.
+ const KPageProperties map_properties = {test_perm, false, false,
+ (cur_mapped_addr == dst_addr)
+ ? DisableMergeAttribute::DisableHead
+ : DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), cur_mapped_addr, cur_block_size / PageSize,
+ cur_block_addr, true, map_properties, OperationType::Map, false));
+
+ // Update tracking extents.
+ cur_mapped_addr += cur_block_size;
+ cur_block_addr = next_entry.phys_addr;
+ cur_block_size = next_entry.block_size;
+ } else {
+ cur_block_size += next_entry.block_size;
+ }
+ tot_block_size += next_entry.block_size;
+ }
+
+ // Handle the last direct-mapped page.
+ if (const KProcessAddress mapped_block_end =
+ aligned_src_start + tot_block_size - cur_block_size;
+ mapped_block_end < mapping_src_end) {
+ const size_t last_block_size = mapping_src_end - mapped_block_end;
+
+ // Map the last block.
+ const KPageProperties map_properties = {test_perm, false, false,
+ (cur_mapped_addr == dst_addr)
+ ? DisableMergeAttribute::DisableHead
+ : DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), cur_mapped_addr, last_block_size / PageSize,
+ cur_block_addr, true, map_properties, OperationType::Map, false));
+
+ // Update tracking extents.
+ cur_mapped_addr += last_block_size;
+ cur_block_addr += last_block_size;
+ if (mapped_block_end + cur_block_size < aligned_src_end &&
+ cur_block_size == last_block_size) {
+ traverse_valid =
+ src_impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
+ ASSERT(traverse_valid);
+
+ cur_block_addr = next_entry.phys_addr;
+ }
+ }
+
+ // Map the end page, if we have one.
+ if (end_partial_page != 0) {
+ // Ensure the page holds correct data.
+ u8* const end_partial_virt = GetHeapVirtualPointer(m_kernel, end_partial_page);
+ if (send) {
+ const size_t copy_size = src_end - mapping_src_end;
+ std::memcpy(end_partial_virt, GetHeapVirtualPointer(m_kernel, cur_block_addr),
+ copy_size);
+ std::memset(end_partial_virt + copy_size, fill_val, PageSize - copy_size);
+ } else {
+ std::memset(end_partial_virt, fill_val, PageSize);
+ }
+
+ // Map the page.
+ const KPageProperties map_properties = {test_perm, false, false,
+ (cur_mapped_addr == dst_addr)
+ ? DisableMergeAttribute::DisableHead
+ : DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), cur_mapped_addr, 1, end_partial_page, true,
+ map_properties, OperationType::Map, false));
+ }
+
+ // Update memory blocks to reflect our changes
+ m_memory_block_manager.Update(std::addressof(allocator), dst_addr, aligned_src_size / PageSize,
+ dst_state, test_perm, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ // Set the output address.
+ *out_addr = dst_addr + (src_start - aligned_src_start);
+
+ // We succeeded.
+ memory_reservation.Commit();
+ R_SUCCEED();
+}
+
+Result KPageTableBase::SetupForIpc(KProcessAddress* out_dst_addr, size_t size,
+ KProcessAddress src_addr, KPageTableBase& src_page_table,
+ KMemoryPermission test_perm, KMemoryState dst_state, bool send) {
+ // For convenience, alias this.
+ KPageTableBase& dst_page_table = *this;
+
+ // Acquire the table locks.
+ KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(std::addressof(src_page_table));
+
+ // Perform client setup.
+ size_t num_allocator_blocks;
+ R_TRY(src_page_table.SetupForIpcClient(updater.GetPageList(),
+ std::addressof(num_allocator_blocks), src_addr, size,
+ test_perm, dst_state));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ src_page_table.m_memory_block_slab_manager,
+ num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Get the mapped extents.
+ const KProcessAddress src_map_start = Common::AlignUp(GetInteger(src_addr), PageSize);
+ const KProcessAddress src_map_end = Common::AlignDown(GetInteger(src_addr) + size, PageSize);
+ const size_t src_map_size = src_map_end - src_map_start;
+
+ // Ensure that we clean up appropriately if we fail after this.
+ const auto src_perm = static_cast<KMemoryPermission>(
+ (test_perm == KMemoryPermission::UserReadWrite)
+ ? KMemoryPermission::KernelReadWrite | KMemoryPermission::NotMapped
+ : KMemoryPermission::UserRead);
+ ON_RESULT_FAILURE {
+ if (src_map_end > src_map_start) {
+ src_page_table.CleanupForIpcClientOnServerSetupFailure(
+ updater.GetPageList(), src_map_start, src_map_size, src_perm);
+ }
+ };
+
+ // Perform server setup.
+ R_TRY(dst_page_table.SetupForIpcServer(out_dst_addr, size, src_addr, test_perm, dst_state,
+ src_page_table, send));
+
+ // If anything was mapped, ipc-lock the pages.
+ if (src_map_start < src_map_end) {
+ // Get the source permission.
+ src_page_table.m_memory_block_manager.UpdateLock(std::addressof(allocator), src_map_start,
+ (src_map_end - src_map_start) / PageSize,
+ &KMemoryBlock::LockForIpc, src_perm);
+ }
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CleanupForIpcServer(KProcessAddress address, size_t size,
+ KMemoryState dst_state) {
+ // Validate the address.
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::All, dst_state, KMemoryPermission::UserRead,
+ KMemoryPermission::UserRead, KMemoryAttribute::All,
+ KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Get aligned extents.
+ const KProcessAddress aligned_start = Common::AlignDown(GetInteger(address), PageSize);
+ const KProcessAddress aligned_end = Common::AlignUp(GetInteger(address) + size, PageSize);
+ const size_t aligned_size = aligned_end - aligned_start;
+ const size_t aligned_num_pages = aligned_size / PageSize;
+
+ // Unmap the pages.
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), aligned_start, aligned_num_pages, 0, false,
+ unmap_properties, OperationType::Unmap, false));
+
+ // Update memory blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), aligned_start, aligned_num_pages,
+ KMemoryState::None, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
+
+ // Release from the resource limit as relevant.
+ const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize);
+ const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize);
+ const size_t mapping_size = (mapping_start < mapping_end) ? mapping_end - mapping_start : 0;
+ m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax,
+ aligned_size - mapping_size);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::CleanupForIpcClient(KProcessAddress address, size_t size,
+ KMemoryState dst_state) {
+ // Validate the address.
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Get aligned source extents.
+ const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize);
+ const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize);
+ const KProcessAddress mapping_last = mapping_end - 1;
+ const size_t mapping_size = (mapping_start < mapping_end) ? (mapping_end - mapping_start) : 0;
+
+ // If nothing was mapped, we're actually done immediately.
+ R_SUCCEED_IF(mapping_size == 0);
+
+ // Get the test state and attribute mask.
+ KMemoryState test_state;
+ KMemoryAttribute test_attr_mask;
+ switch (dst_state) {
+ case KMemoryState::Ipc:
+ test_state = KMemoryState::FlagCanUseIpc;
+ test_attr_mask =
+ KMemoryAttribute::Uncached | KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked;
+ break;
+ case KMemoryState::NonSecureIpc:
+ test_state = KMemoryState::FlagCanUseNonSecureIpc;
+ test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
+ break;
+ case KMemoryState::NonDeviceIpc:
+ test_state = KMemoryState::FlagCanUseNonDeviceIpc;
+ test_attr_mask = KMemoryAttribute::Uncached | KMemoryAttribute::Locked;
+ break;
+ default:
+ R_THROW(ResultInvalidCombination);
+ }
+
+ // Lock the table.
+ // NOTE: Nintendo does this *after* creating the updater below, but this does not follow
+ // convention elsewhere in KPageTableBase.
+ KScopedLightLock lk(m_general_lock);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Ensure that on failure, we roll back appropriately.
+ size_t mapped_size = 0;
+ ON_RESULT_FAILURE {
+ if (mapped_size > 0) {
+ // Determine where the mapping ends.
+ const auto mapped_end = GetInteger(mapping_start) + mapped_size;
+ const auto mapped_last = mapped_end - 1;
+
+ // Get current and next iterators.
+ KMemoryBlockManager::const_iterator start_it =
+ m_memory_block_manager.FindIterator(mapping_start);
+ KMemoryBlockManager::const_iterator next_it = start_it;
+ ++next_it;
+
+ // Get the current block info.
+ KMemoryInfo cur_info = start_it->GetMemoryInfo();
+
+ // Create tracking variables.
+ KProcessAddress cur_address = cur_info.GetAddress();
+ size_t cur_size = cur_info.GetSize();
+ bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission();
+ bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1;
+ bool first = cur_info.GetIpcDisableMergeCount() == 1 &&
+ False(cur_info.GetDisableMergeAttribute() &
+ KMemoryBlockDisableMergeAttribute::Locked);
+
+ while ((GetInteger(cur_address) + cur_size - 1) < mapped_last) {
+ // Check that we have a next block.
+ ASSERT(next_it != m_memory_block_manager.end());
+
+ // Get the next info.
+ const KMemoryInfo next_info = next_it->GetMemoryInfo();
+
+ // Check if we can consolidate the next block's permission set with the current one.
+ const bool next_perm_eq =
+ next_info.GetPermission() == next_info.GetOriginalPermission();
+ const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1;
+ if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm &&
+ cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) {
+ // We can consolidate the reprotection for the current and next block into a
+ // single call.
+ cur_size += next_info.GetSize();
+ } else {
+ // We have to operate on the current block.
+ if ((cur_needs_set_perm || first) && !cur_perm_eq) {
+ const KPageProperties properties = {
+ cur_info.GetPermission(), false, false,
+ first ? DisableMergeAttribute::EnableAndMergeHeadBodyTail
+ : DisableMergeAttribute::None};
+ R_ASSERT(this->Operate(updater.GetPageList(), cur_address,
+ cur_size / PageSize, 0, false, properties,
+ OperationType::ChangePermissions, true));
+ }
+
+ // Advance.
+ cur_address = next_info.GetAddress();
+ cur_size = next_info.GetSize();
+ first = false;
+ }
+
+ // Advance.
+ cur_info = next_info;
+ cur_perm_eq = next_perm_eq;
+ cur_needs_set_perm = next_needs_set_perm;
+ ++next_it;
+ }
+
+ // Process the last block.
+ if ((first || cur_needs_set_perm) && !cur_perm_eq) {
+ const KPageProperties properties = {
+ cur_info.GetPermission(), false, false,
+ first ? DisableMergeAttribute::EnableAndMergeHeadBodyTail
+ : DisableMergeAttribute::None};
+ R_ASSERT(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, 0,
+ false, properties, OperationType::ChangePermissions, true));
+ }
+ }
+ };
+
+ // Iterate, reprotecting as needed.
+ {
+ // Get current and next iterators.
+ KMemoryBlockManager::const_iterator start_it =
+ m_memory_block_manager.FindIterator(mapping_start);
+ KMemoryBlockManager::const_iterator next_it = start_it;
+ ++next_it;
+
+ // Validate the current block.
+ KMemoryInfo cur_info = start_it->GetMemoryInfo();
+ R_ASSERT(this->CheckMemoryState(
+ cur_info, test_state, test_state, KMemoryPermission::None, KMemoryPermission::None,
+ test_attr_mask | KMemoryAttribute::IpcLocked, KMemoryAttribute::IpcLocked));
+
+ // Create tracking variables.
+ KProcessAddress cur_address = cur_info.GetAddress();
+ size_t cur_size = cur_info.GetSize();
+ bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission();
+ bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1;
+ bool first =
+ cur_info.GetIpcDisableMergeCount() == 1 &&
+ False(cur_info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute::Locked);
+
+ while ((cur_address + cur_size - 1) < mapping_last) {
+ // Check that we have a next block.
+ ASSERT(next_it != m_memory_block_manager.end());
+
+ // Get the next info.
+ const KMemoryInfo next_info = next_it->GetMemoryInfo();
+
+ // Validate the next block.
+ R_ASSERT(this->CheckMemoryState(
+ next_info, test_state, test_state, KMemoryPermission::None, KMemoryPermission::None,
+ test_attr_mask | KMemoryAttribute::IpcLocked, KMemoryAttribute::IpcLocked));
+
+ // Check if we can consolidate the next block's permission set with the current one.
+ const bool next_perm_eq =
+ next_info.GetPermission() == next_info.GetOriginalPermission();
+ const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1;
+ if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm &&
+ cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) {
+ // We can consolidate the reprotection for the current and next block into a single
+ // call.
+ cur_size += next_info.GetSize();
+ } else {
+ // We have to operate on the current block.
+ if ((cur_needs_set_perm || first) && !cur_perm_eq) {
+ const KPageProperties properties = {
+ cur_needs_set_perm ? cur_info.GetOriginalPermission()
+ : cur_info.GetPermission(),
+ false, false,
+ first ? DisableMergeAttribute::EnableHeadAndBody
+ : DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, 0,
+ false, properties, OperationType::ChangePermissions,
+ false));
+ }
+
+ // Mark that we mapped the block.
+ mapped_size += cur_size;
+
+ // Advance.
+ cur_address = next_info.GetAddress();
+ cur_size = next_info.GetSize();
+ first = false;
+ }
+
+ // Advance.
+ cur_info = next_info;
+ cur_perm_eq = next_perm_eq;
+ cur_needs_set_perm = next_needs_set_perm;
+ ++next_it;
+ }
+
+ // Process the last block.
+ const auto lock_count =
+ cur_info.GetIpcLockCount() +
+ (next_it != m_memory_block_manager.end()
+ ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount())
+ : 0);
+ if ((first || cur_needs_set_perm || (lock_count == 1)) && !cur_perm_eq) {
+ const DisableMergeAttribute head_body_attr =
+ first ? DisableMergeAttribute::EnableHeadAndBody : DisableMergeAttribute::None;
+ const DisableMergeAttribute tail_attr =
+ lock_count == 1 ? DisableMergeAttribute::EnableTail : DisableMergeAttribute::None;
+ const KPageProperties properties = {
+ cur_needs_set_perm ? cur_info.GetOriginalPermission() : cur_info.GetPermission(),
+ false, false, static_cast<DisableMergeAttribute>(head_body_attr | tail_attr)};
+ R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, 0, false,
+ properties, OperationType::ChangePermissions, false));
+ }
+ }
+
+ // Create an update allocator.
+ // NOTE: Guaranteed zero blocks needed here.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, 0);
+ R_TRY(allocator_result);
+
+ // Unlock the pages.
+ m_memory_block_manager.UpdateLock(std::addressof(allocator), mapping_start,
+ mapping_size / PageSize, &KMemoryBlock::UnlockForIpc,
+ KMemoryPermission::None);
+
+ R_SUCCEED();
+}
+
+void KPageTableBase::CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list,
+ KProcessAddress address, size_t size,
+ KMemoryPermission prot_perm) {
+ ASSERT(this->IsLockedByCurrentThread());
+ ASSERT(Common::IsAligned(GetInteger(address), PageSize));
+ ASSERT(Common::IsAligned(size, PageSize));
+
+ // Get the mapped extents.
+ const KProcessAddress src_map_start = address;
+ const KProcessAddress src_map_end = address + size;
+ const KProcessAddress src_map_last = src_map_end - 1;
+
+ // This function is only invoked when there's something to do.
+ ASSERT(src_map_end > src_map_start);
+
+ // Iterate over blocks, fixing permissions.
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address);
+ while (true) {
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ const auto cur_start = info.GetAddress() >= GetInteger(src_map_start)
+ ? info.GetAddress()
+ : GetInteger(src_map_start);
+ const auto cur_end =
+ src_map_last <= info.GetLastAddress() ? src_map_end : info.GetEndAddress();
+
+ // If we can, fix the protections on the block.
+ if ((info.GetIpcLockCount() == 0 &&
+ (info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm) ||
+ (info.GetIpcLockCount() != 0 &&
+ (info.GetOriginalPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm)) {
+ // Check if we actually need to fix the protections on the block.
+ if (cur_end == src_map_end || info.GetAddress() <= GetInteger(src_map_start) ||
+ (info.GetPermission() & KMemoryPermission::IpcLockChangeMask) != prot_perm) {
+ const bool start_nc = (info.GetAddress() == GetInteger(src_map_start))
+ ? (False(info.GetDisableMergeAttribute() &
+ (KMemoryBlockDisableMergeAttribute::Locked |
+ KMemoryBlockDisableMergeAttribute::IpcLeft)))
+ : info.GetAddress() <= GetInteger(src_map_start);
+
+ const DisableMergeAttribute head_body_attr =
+ start_nc ? DisableMergeAttribute::EnableHeadAndBody
+ : DisableMergeAttribute::None;
+ DisableMergeAttribute tail_attr;
+ if (cur_end == src_map_end && info.GetEndAddress() == src_map_end) {
+ auto next_it = it;
+ ++next_it;
+
+ const auto lock_count =
+ info.GetIpcLockCount() +
+ (next_it != m_memory_block_manager.end()
+ ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount())
+ : 0);
+ tail_attr = lock_count == 0 ? DisableMergeAttribute::EnableTail
+ : DisableMergeAttribute::None;
+ } else {
+ tail_attr = DisableMergeAttribute::None;
+ }
+
+ const KPageProperties properties = {
+ info.GetPermission(), false, false,
+ static_cast<DisableMergeAttribute>(head_body_attr | tail_attr)};
+ R_ASSERT(this->Operate(page_list, cur_start, (cur_end - cur_start) / PageSize, 0,
+ false, properties, OperationType::ChangePermissions, true));
+ }
+ }
+
+ // If we're past the end of the region, we're done.
+ if (src_map_last <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ ++it;
+ ASSERT(it != m_memory_block_manager.end());
+ }
+}
+
+Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) {
+ // Lock the physical memory lock.
+ KScopedLightLock phys_lk(m_map_physical_memory_lock);
+
+ // Calculate the last address for convenience.
+ const KProcessAddress last_address = address + size - 1;
+
+ // Define iteration variables.
+ KProcessAddress cur_address;
+ size_t mapped_size;
+
+ // The entire mapping process can be retried.
+ while (true) {
+ // Check if the memory is already mapped.
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Iterate over the memory.
+ cur_address = address;
+ mapped_size = 0;
+
+ auto it = m_memory_block_manager.FindIterator(cur_address);
+ while (true) {
+ // Check that the iterator is valid.
+ ASSERT(it != m_memory_block_manager.end());
+
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // Check if we're done.
+ if (last_address <= info.GetLastAddress()) {
+ if (info.GetState() != KMemoryState::Free) {
+ mapped_size += (last_address + 1 - cur_address);
+ }
+ break;
+ }
+
+ // Track the memory if it's mapped.
+ if (info.GetState() != KMemoryState::Free) {
+ mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address;
+ }
+
+ // Advance.
+ cur_address = info.GetEndAddress();
+ ++it;
+ }
+
+ // If the size mapped is the size requested, we've nothing to do.
+ R_SUCCEED_IF(size == mapped_size);
+ }
+
+ // Allocate and map the memory.
+ {
+ // Reserve the memory from the process resource limit.
+ KScopedResourceReservation memory_reservation(
+ m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, size - mapped_size);
+ R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
+
+ // Allocate pages for the new memory.
+ KPageGroup pg(m_kernel, m_block_info_manager);
+ R_TRY(m_kernel.MemoryManager().AllocateForProcess(
+ std::addressof(pg), (size - mapped_size) / PageSize, m_allocate_option,
+ GetCurrentProcess(m_kernel).GetId(), m_heap_fill_value));
+
+ // If we fail in the next bit (or retry), we need to cleanup the pages.
+ auto pg_guard = SCOPE_GUARD({
+ pg.OpenFirst();
+ pg.Close();
+ });
+
+ // Map the memory.
+ {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ size_t num_allocator_blocks = 0;
+
+ // Verify that nobody has mapped memory since we first checked.
+ {
+ // Iterate over the memory.
+ size_t checked_mapped_size = 0;
+ cur_address = address;
+
+ auto it = m_memory_block_manager.FindIterator(cur_address);
+ while (true) {
+ // Check that the iterator is valid.
+ ASSERT(it != m_memory_block_manager.end());
+
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ const bool is_free = info.GetState() == KMemoryState::Free;
+ if (is_free) {
+ if (info.GetAddress() < GetInteger(address)) {
+ ++num_allocator_blocks;
+ }
+ if (last_address < info.GetLastAddress()) {
+ ++num_allocator_blocks;
+ }
+ }
+
+ // Check if we're done.
+ if (last_address <= info.GetLastAddress()) {
+ if (!is_free) {
+ checked_mapped_size += (last_address + 1 - cur_address);
+ }
+ break;
+ }
+
+ // Track the memory if it's mapped.
+ if (!is_free) {
+ checked_mapped_size +=
+ KProcessAddress(info.GetEndAddress()) - cur_address;
+ }
+
+ // Advance.
+ cur_address = info.GetEndAddress();
+ ++it;
+ }
+
+ // If the size now isn't what it was before, somebody mapped or unmapped
+ // concurrently. If this happened, retry.
+ if (mapped_size != checked_mapped_size) {
+ continue;
+ }
+ }
+
+ // Create an update allocator.
+ ASSERT(num_allocator_blocks <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager,
+ num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Prepare to iterate over the memory.
+ auto pg_it = pg.begin();
+ KPhysicalAddress pg_phys_addr = pg_it->GetAddress();
+ size_t pg_pages = pg_it->GetNumPages();
+
+ // Reset the current tracking address, and make sure we clean up on failure.
+ pg_guard.Cancel();
+ cur_address = address;
+ ON_RESULT_FAILURE {
+ if (cur_address > address) {
+ const KProcessAddress last_unmap_address = cur_address - 1;
+
+ // Iterate, unmapping the pages.
+ cur_address = address;
+
+ auto it = m_memory_block_manager.FindIterator(cur_address);
+ while (true) {
+ // Check that the iterator is valid.
+ ASSERT(it != m_memory_block_manager.end());
+
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // If the memory state is free, we mapped it and need to unmap it.
+ if (info.GetState() == KMemoryState::Free) {
+ // Determine the range to unmap.
+ const KPageProperties unmap_properties = {
+ KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ const size_t cur_pages =
+ std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
+ last_unmap_address + 1 - cur_address) /
+ PageSize;
+
+ // Unmap.
+ R_ASSERT(this->Operate(updater.GetPageList(), cur_address,
+ cur_pages, 0, false, unmap_properties,
+ OperationType::Unmap, true));
+ }
+
+ // Check if we're done.
+ if (last_unmap_address <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ cur_address = info.GetEndAddress();
+ ++it;
+ }
+ }
+
+ // Release any remaining unmapped memory.
+ m_kernel.MemoryManager().OpenFirst(pg_phys_addr, pg_pages);
+ m_kernel.MemoryManager().Close(pg_phys_addr, pg_pages);
+ for (++pg_it; pg_it != pg.end(); ++pg_it) {
+ m_kernel.MemoryManager().OpenFirst(pg_it->GetAddress(),
+ pg_it->GetNumPages());
+ m_kernel.MemoryManager().Close(pg_it->GetAddress(), pg_it->GetNumPages());
+ }
+ };
+
+ auto it = m_memory_block_manager.FindIterator(cur_address);
+ while (true) {
+ // Check that the iterator is valid.
+ ASSERT(it != m_memory_block_manager.end());
+
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // If it's unmapped, we need to map it.
+ if (info.GetState() == KMemoryState::Free) {
+ // Determine the range to map.
+ const KPageProperties map_properties = {
+ KMemoryPermission::UserReadWrite, false, false,
+ cur_address == this->GetAliasRegionStart()
+ ? DisableMergeAttribute::DisableHead
+ : DisableMergeAttribute::None};
+ size_t map_pages =
+ std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
+ last_address + 1 - cur_address) /
+ PageSize;
+
+ // While we have pages to map, map them.
+ {
+ // Create a page group for the current mapping range.
+ KPageGroup cur_pg(m_kernel, m_block_info_manager);
+ {
+ ON_RESULT_FAILURE_2 {
+ cur_pg.OpenFirst();
+ cur_pg.Close();
+ };
+
+ size_t remain_pages = map_pages;
+ while (remain_pages > 0) {
+ // Check if we're at the end of the physical block.
+ if (pg_pages == 0) {
+ // Ensure there are more pages to map.
+ ASSERT(pg_it != pg.end());
+
+ // Advance our physical block.
+ ++pg_it;
+ pg_phys_addr = pg_it->GetAddress();
+ pg_pages = pg_it->GetNumPages();
+ }
+
+ // Add whatever we can to the current block.
+ const size_t cur_pages = std::min(pg_pages, remain_pages);
+ R_TRY(cur_pg.AddBlock(pg_phys_addr +
+ ((pg_pages - cur_pages) * PageSize),
+ cur_pages));
+
+ // Advance.
+ remain_pages -= cur_pages;
+ pg_pages -= cur_pages;
+ }
+ }
+
+ // Map the papges.
+ R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages,
+ cur_pg, map_properties,
+ OperationType::MapFirstGroup, false));
+ }
+ }
+
+ // Check if we're done.
+ if (last_address <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ cur_address = info.GetEndAddress();
+ ++it;
+ }
+
+ // We succeeded, so commit the memory reservation.
+ memory_reservation.Commit();
+
+ // Increase our tracked mapped size.
+ m_mapped_physical_memory_size += (size - mapped_size);
+
+ // Update the relevant memory blocks.
+ m_memory_block_manager.UpdateIfMatch(
+ std::addressof(allocator), address, size / PageSize, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryAttribute::None, KMemoryState::Normal,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ address == this->GetAliasRegionStart()
+ ? KMemoryBlockDisableMergeAttribute::Normal
+ : KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ R_SUCCEED();
+ }
+ }
+ }
+}
+
+Result KPageTableBase::UnmapPhysicalMemory(KProcessAddress address, size_t size) {
+ // Lock the physical memory lock.
+ KScopedLightLock phys_lk(m_map_physical_memory_lock);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Calculate the last address for convenience.
+ const KProcessAddress last_address = address + size - 1;
+
+ // Define iteration variables.
+ KProcessAddress map_start_address = 0;
+ KProcessAddress map_last_address = 0;
+
+ KProcessAddress cur_address;
+ size_t mapped_size;
+ size_t num_allocator_blocks = 0;
+
+ // Check if the memory is mapped.
+ {
+ // Iterate over the memory.
+ cur_address = address;
+ mapped_size = 0;
+
+ auto it = m_memory_block_manager.FindIterator(cur_address);
+ while (true) {
+ // Check that the iterator is valid.
+ ASSERT(it != m_memory_block_manager.end());
+
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // Verify the memory's state.
+ const bool is_normal = info.GetState() == KMemoryState::Normal &&
+ info.GetAttribute() == KMemoryAttribute::None;
+ const bool is_free = info.GetState() == KMemoryState::Free;
+ R_UNLESS(is_normal || is_free, ResultInvalidCurrentMemory);
+
+ if (is_normal) {
+ R_UNLESS(info.GetAttribute() == KMemoryAttribute::None, ResultInvalidCurrentMemory);
+
+ if (map_start_address == 0) {
+ map_start_address = cur_address;
+ }
+ map_last_address =
+ (last_address >= info.GetLastAddress()) ? info.GetLastAddress() : last_address;
+
+ if (info.GetAddress() < GetInteger(address)) {
+ ++num_allocator_blocks;
+ }
+ if (last_address < info.GetLastAddress()) {
+ ++num_allocator_blocks;
+ }
+
+ mapped_size += (map_last_address + 1 - cur_address);
+ }
+
+ // Check if we're done.
+ if (last_address <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ cur_address = info.GetEndAddress();
+ ++it;
+ }
+
+ // If there's nothing mapped, we've nothing to do.
+ R_SUCCEED_IF(mapped_size == 0);
+ }
+
+ // Create an update allocator.
+ ASSERT(num_allocator_blocks <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Separate the mapping.
+ const KPageProperties sep_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), map_start_address,
+ (map_last_address + 1 - map_start_address) / PageSize, 0, false,
+ sep_properties, OperationType::Separate, false));
+
+ // Reset the current tracking address, and make sure we clean up on failure.
+ cur_address = address;
+
+ // Iterate over the memory, unmapping as we go.
+ auto it = m_memory_block_manager.FindIterator(cur_address);
+
+ const auto clear_merge_attr =
+ (it->GetState() == KMemoryState::Normal &&
+ it->GetAddress() == this->GetAliasRegionStart() && it->GetAddress() == address)
+ ? KMemoryBlockDisableMergeAttribute::Normal
+ : KMemoryBlockDisableMergeAttribute::None;
+
+ while (true) {
+ // Check that the iterator is valid.
+ ASSERT(it != m_memory_block_manager.end());
+
+ // Get the memory info.
+ const KMemoryInfo info = it->GetMemoryInfo();
+
+ // If the memory state is normal, we need to unmap it.
+ if (info.GetState() == KMemoryState::Normal) {
+ // Determine the range to unmap.
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address,
+ last_address + 1 - cur_address) /
+ PageSize;
+
+ // Unmap.
+ R_ASSERT(this->Operate(updater.GetPageList(), cur_address, cur_pages, 0, false,
+ unmap_properties, OperationType::Unmap, false));
+ }
+
+ // Check if we're done.
+ if (last_address <= info.GetLastAddress()) {
+ break;
+ }
+
+ // Advance.
+ cur_address = info.GetEndAddress();
+ ++it;
+ }
+
+ // Release the memory resource.
+ m_mapped_physical_memory_size -= mapped_size;
+ m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, mapped_size);
+
+ // Update memory blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize,
+ KMemoryState::Free, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ clear_merge_attr);
+
+ // We succeeded.
+ R_SUCCEED();
+}
+
+Result KPageTableBase::MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size) {
+ UNIMPLEMENTED();
+ R_THROW(ResultNotImplemented);
+}
+
+Result KPageTableBase::UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size) {
+ UNIMPLEMENTED();
+ R_THROW(ResultNotImplemented);
+}
+
+Result KPageTableBase::UnmapProcessMemory(KProcessAddress dst_address, size_t size,
+ KPageTableBase& src_page_table,
+ KProcessAddress src_address) {
+ // We need to lock both this table, and the current process's table, so set up an alias.
+ KPageTableBase& dst_page_table = *this;
+
+ // Acquire the table locks.
+ KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock);
+
+ // Check that the memory is mapped in the destination process.
+ size_t num_allocator_blocks;
+ R_TRY(dst_page_table.CheckMemoryState(
+ std::addressof(num_allocator_blocks), dst_address, size, KMemoryState::All,
+ KMemoryState::SharedCode, KMemoryPermission::UserReadWrite,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None));
+
+ // Check that the memory is mapped in the source process.
+ R_TRY(src_page_table.CheckMemoryState(src_address, size, KMemoryState::FlagCanMapProcess,
+ KMemoryState::FlagCanMapProcess, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All,
+ KMemoryAttribute::None));
+
+ // Validate that the memory ranges are compatible.
+ {
+ // Define a helper type.
+ struct ContiguousRangeInfo {
+ public:
+ KPageTableBase& m_pt;
+ TraversalContext m_context;
+ TraversalEntry m_entry;
+ KPhysicalAddress m_phys_addr;
+ size_t m_cur_size;
+ size_t m_remaining_size;
+
+ public:
+ ContiguousRangeInfo(KPageTableBase& pt, KProcessAddress address, size_t size)
+ : m_pt(pt), m_remaining_size(size) {
+ // Begin a traversal.
+ ASSERT(m_pt.GetImpl().BeginTraversal(std::addressof(m_entry),
+ std::addressof(m_context), address));
+
+ // Setup tracking fields.
+ m_phys_addr = m_entry.phys_addr;
+ m_cur_size = std::min<size_t>(
+ m_remaining_size,
+ m_entry.block_size - (GetInteger(m_phys_addr) & (m_entry.block_size - 1)));
+
+ // Consume the whole contiguous block.
+ this->DetermineContiguousBlockExtents();
+ }
+
+ void ContinueTraversal() {
+ // Update our remaining size.
+ m_remaining_size = m_remaining_size - m_cur_size;
+
+ // Update our tracking fields.
+ if (m_remaining_size > 0) {
+ m_phys_addr = m_entry.phys_addr;
+ m_cur_size = std::min<size_t>(m_remaining_size, m_entry.block_size);
+
+ // Consume the whole contiguous block.
+ this->DetermineContiguousBlockExtents();
+ }
+ }
+
+ private:
+ void DetermineContiguousBlockExtents() {
+ // Continue traversing until we're not contiguous, or we have enough.
+ while (m_cur_size < m_remaining_size) {
+ ASSERT(m_pt.GetImpl().ContinueTraversal(std::addressof(m_entry),
+ std::addressof(m_context)));
+
+ // If we're not contiguous, we're done.
+ if (m_entry.phys_addr != m_phys_addr + m_cur_size) {
+ break;
+ }
+
+ // Update our current size.
+ m_cur_size = std::min(m_remaining_size, m_cur_size + m_entry.block_size);
+ }
+ }
+ };
+
+ // Create ranges for both tables.
+ ContiguousRangeInfo src_range(src_page_table, src_address, size);
+ ContiguousRangeInfo dst_range(dst_page_table, dst_address, size);
+
+ // Validate the ranges.
+ while (src_range.m_remaining_size > 0 && dst_range.m_remaining_size > 0) {
+ R_UNLESS(src_range.m_phys_addr == dst_range.m_phys_addr, ResultInvalidMemoryRegion);
+ R_UNLESS(src_range.m_cur_size == dst_range.m_cur_size, ResultInvalidMemoryRegion);
+
+ src_range.ContinueTraversal();
+ dst_range.ContinueTraversal();
+ }
+ }
+
+ // We no longer need to hold our lock on the source page table.
+ lk.TryUnlockHalf(src_page_table.m_general_lock);
+
+ // Create an update allocator.
+ Result allocator_result;
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // We're going to perform an update, so create a helper.
+ KScopedPageTableUpdater updater(this);
+
+ // Unmap the memory.
+ const size_t num_pages = size / PageSize;
+ const KPageProperties unmap_properties = {KMemoryPermission::None, false, false,
+ DisableMergeAttribute::None};
+ R_TRY(this->Operate(updater.GetPageList(), dst_address, num_pages, 0, false, unmap_properties,
+ OperationType::Unmap, false));
+
+ // Apply the memory block update.
+ m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages,
+ KMemoryState::Free, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
+
+ R_SUCCEED();
+}
+
+Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_addr,
+ size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid,
+ const KPageProperties properties, OperationType operation,
+ bool reuse_ll) {
+ ASSERT(this->IsLockedByCurrentThread());
+ ASSERT(num_pages > 0);
+ ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
+ ASSERT(this->ContainsPages(virt_addr, num_pages));
+
+ // As we don't allocate page entries in guest memory, we don't need to allocate them from
+ // or free them to the page list, and so it goes unused (along with page properties).
+
+ switch (operation) {
+ case OperationType::Unmap: {
+ // Ensure that any pages we track are closed on exit.
+ KPageGroup pages_to_close(m_kernel, this->GetBlockInfoManager());
+ SCOPE_EXIT({ pages_to_close.CloseAndReset(); });
+
+ // Make a page group representing the region to unmap.
+ this->MakePageGroup(pages_to_close, virt_addr, num_pages);
+
+ // Unmap.
+ m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize);
+
+ R_SUCCEED();
+ }
+ case OperationType::Map: {
+ ASSERT(virt_addr != 0);
+ ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
+ m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr);
+
+ // Open references to pages, if we should.
+ if (this->IsHeapPhysicalAddress(phys_addr)) {
+ m_kernel.MemoryManager().Open(phys_addr, num_pages);
+ }
+
+ R_SUCCEED();
+ }
+ case OperationType::Separate: {
+ // TODO: Unimplemented.
+ R_SUCCEED();
+ }
+ case OperationType::ChangePermissions:
+ case OperationType::ChangePermissionsAndRefresh:
+ case OperationType::ChangePermissionsAndRefreshAndFlush:
+ R_SUCCEED();
+ default:
+ UNREACHABLE();
+ }
+}
+
+Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_addr,
+ size_t num_pages, const KPageGroup& page_group,
+ const KPageProperties properties, OperationType operation,
+ bool reuse_ll) {
+ ASSERT(this->IsLockedByCurrentThread());
+ ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
+ ASSERT(num_pages > 0);
+ ASSERT(num_pages == page_group.GetNumPages());
+
+ // As we don't allocate page entries in guest memory, we don't need to allocate them from
+ // the page list, and so it goes unused (along with page properties).
+
+ switch (operation) {
+ case OperationType::MapGroup:
+ case OperationType::MapFirstGroup: {
+ // We want to maintain a new reference to every page in the group.
+ KScopedPageGroup spg(page_group, operation != OperationType::MapFirstGroup);
+
+ for (const auto& node : page_group) {
+ const size_t size{node.GetNumPages() * PageSize};
+
+ // Map the pages.
+ m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress());
+
+ virt_addr += size;
+ }
+
+ // We succeeded! We want to persist the reference to the pages.
+ spg.CancelClose();
+
+ R_SUCCEED();
+ }
+ default:
+ UNREACHABLE();
+ }
+}
+
+void KPageTableBase::FinalizeUpdate(PageLinkedList* page_list) {
+ while (page_list->Peek()) {
+ [[maybe_unused]] auto page = page_list->Pop();
+
+ // TODO: Free page entries once they are allocated in guest memory.
+ // ASSERT(this->GetPageTableManager().IsInPageTableHeap(page));
+ // ASSERT(this->GetPageTableManager().GetRefCount(page) == 0);
+ // this->GetPageTableManager().Free(page);
+ }
+}
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h
new file mode 100644
index 000000000..ee2c41e67
--- /dev/null
+++ b/src/core/hle/kernel/k_page_table_base.h
@@ -0,0 +1,759 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <memory>
+
+#include "common/common_funcs.h"
+#include "common/page_table.h"
+#include "core/core.h"
+#include "core/hle/kernel/k_dynamic_resource_manager.h"
+#include "core/hle/kernel/k_light_lock.h"
+#include "core/hle/kernel/k_memory_block.h"
+#include "core/hle/kernel/k_memory_block_manager.h"
+#include "core/hle/kernel/k_memory_layout.h"
+#include "core/hle/kernel/k_memory_manager.h"
+#include "core/hle/kernel/k_typed_address.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/result.h"
+#include "core/memory.h"
+
+namespace Kernel {
+
+enum class DisableMergeAttribute : u8 {
+ None = (0U << 0),
+
+ DisableHead = (1U << 0),
+ DisableHeadAndBody = (1U << 1),
+ EnableHeadAndBody = (1U << 2),
+ DisableTail = (1U << 3),
+ EnableTail = (1U << 4),
+ EnableAndMergeHeadBodyTail = (1U << 5),
+
+ EnableHeadBodyTail = EnableHeadAndBody | EnableTail,
+ DisableHeadBodyTail = DisableHeadAndBody | DisableTail,
+};
+DECLARE_ENUM_FLAG_OPERATORS(DisableMergeAttribute);
+
+struct KPageProperties {
+ KMemoryPermission perm;
+ bool io;
+ bool uncached;
+ DisableMergeAttribute disable_merge_attributes;
+};
+static_assert(std::is_trivial_v<KPageProperties>);
+static_assert(sizeof(KPageProperties) == sizeof(u32));
+
+class KResourceLimit;
+class KSystemResource;
+
+class KPageTableBase {
+ YUZU_NON_COPYABLE(KPageTableBase);
+ YUZU_NON_MOVEABLE(KPageTableBase);
+
+public:
+ using TraversalEntry = Common::PageTable::TraversalEntry;
+ using TraversalContext = Common::PageTable::TraversalContext;
+
+ class MemoryRange {
+ private:
+ KernelCore& m_kernel;
+ KPhysicalAddress m_address;
+ size_t m_size;
+ bool m_heap;
+
+ public:
+ explicit MemoryRange(KernelCore& kernel)
+ : m_kernel(kernel), m_address(0), m_size(0), m_heap(false) {}
+
+ void Set(KPhysicalAddress address, size_t size, bool heap) {
+ m_address = address;
+ m_size = size;
+ m_heap = heap;
+ }
+
+ KPhysicalAddress GetAddress() const {
+ return m_address;
+ }
+ size_t GetSize() const {
+ return m_size;
+ }
+ bool IsHeap() const {
+ return m_heap;
+ }
+
+ void Open();
+ void Close();
+ };
+
+protected:
+ enum MemoryFillValue : u8 {
+ MemoryFillValue_Zero = 0,
+ MemoryFillValue_Stack = 'X',
+ MemoryFillValue_Ipc = 'Y',
+ MemoryFillValue_Heap = 'Z',
+ };
+
+ enum class OperationType {
+ Map = 0,
+ MapGroup = 1,
+ MapFirstGroup = 2,
+ Unmap = 3,
+ ChangePermissions = 4,
+ ChangePermissionsAndRefresh = 5,
+ ChangePermissionsAndRefreshAndFlush = 6,
+ Separate = 7,
+ };
+
+ static constexpr size_t MaxPhysicalMapAlignment = 1_GiB;
+ static constexpr size_t RegionAlignment = 2_MiB;
+ static_assert(RegionAlignment == KernelAslrAlignment);
+
+ struct PageLinkedList {
+ private:
+ struct Node {
+ Node* m_next;
+ std::array<u8, PageSize - sizeof(Node*)> m_buffer;
+ };
+ static_assert(std::is_trivial_v<Node>);
+
+ private:
+ Node* m_root{};
+
+ public:
+ constexpr PageLinkedList() : m_root(nullptr) {}
+
+ void Push(Node* n) {
+ ASSERT(Common::IsAligned(reinterpret_cast<uintptr_t>(n), PageSize));
+ n->m_next = m_root;
+ m_root = n;
+ }
+
+ Node* Peek() const {
+ return m_root;
+ }
+
+ Node* Pop() {
+ Node* const r = m_root;
+
+ m_root = r->m_next;
+ r->m_next = nullptr;
+
+ return r;
+ }
+ };
+ static_assert(std::is_trivially_destructible_v<PageLinkedList>);
+
+ static constexpr auto DefaultMemoryIgnoreAttr =
+ KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared;
+
+ static constexpr size_t GetAddressSpaceWidth(Svc::CreateProcessFlag as_type) {
+ switch (static_cast<Svc::CreateProcessFlag>(as_type &
+ Svc::CreateProcessFlag::AddressSpaceMask)) {
+ case Svc::CreateProcessFlag::AddressSpace64Bit:
+ return 39;
+ case Svc::CreateProcessFlag::AddressSpace64BitDeprecated:
+ return 36;
+ case Svc::CreateProcessFlag::AddressSpace32Bit:
+ case Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias:
+ return 32;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+private:
+ class KScopedPageTableUpdater {
+ private:
+ KPageTableBase* m_pt;
+ PageLinkedList m_ll;
+
+ public:
+ explicit KScopedPageTableUpdater(KPageTableBase* pt) : m_pt(pt), m_ll() {}
+ explicit KScopedPageTableUpdater(KPageTableBase& pt)
+ : KScopedPageTableUpdater(std::addressof(pt)) {}
+ ~KScopedPageTableUpdater() {
+ m_pt->FinalizeUpdate(this->GetPageList());
+ }
+
+ PageLinkedList* GetPageList() {
+ return std::addressof(m_ll);
+ }
+ };
+
+private:
+ KernelCore& m_kernel;
+ Core::System& m_system;
+ KProcessAddress m_address_space_start{};
+ KProcessAddress m_address_space_end{};
+ KProcessAddress m_heap_region_start{};
+ KProcessAddress m_heap_region_end{};
+ KProcessAddress m_current_heap_end{};
+ KProcessAddress m_alias_region_start{};
+ KProcessAddress m_alias_region_end{};
+ KProcessAddress m_stack_region_start{};
+ KProcessAddress m_stack_region_end{};
+ KProcessAddress m_kernel_map_region_start{};
+ KProcessAddress m_kernel_map_region_end{};
+ KProcessAddress m_alias_code_region_start{};
+ KProcessAddress m_alias_code_region_end{};
+ KProcessAddress m_code_region_start{};
+ KProcessAddress m_code_region_end{};
+ size_t m_max_heap_size{};
+ size_t m_mapped_physical_memory_size{};
+ size_t m_mapped_unsafe_physical_memory{};
+ size_t m_mapped_insecure_memory{};
+ size_t m_mapped_ipc_server_memory{};
+ mutable KLightLock m_general_lock;
+ mutable KLightLock m_map_physical_memory_lock;
+ KLightLock m_device_map_lock;
+ std::unique_ptr<Common::PageTable> m_impl{};
+ Core::Memory::Memory* m_memory{};
+ KMemoryBlockManager m_memory_block_manager{};
+ u32 m_allocate_option{};
+ u32 m_address_space_width{};
+ bool m_is_kernel{};
+ bool m_enable_aslr{};
+ bool m_enable_device_address_space_merge{};
+ KMemoryBlockSlabManager* m_memory_block_slab_manager{};
+ KBlockInfoManager* m_block_info_manager{};
+ KResourceLimit* m_resource_limit{};
+ const KMemoryRegion* m_cached_physical_linear_region{};
+ const KMemoryRegion* m_cached_physical_heap_region{};
+ MemoryFillValue m_heap_fill_value{};
+ MemoryFillValue m_ipc_fill_value{};
+ MemoryFillValue m_stack_fill_value{};
+
+public:
+ explicit KPageTableBase(KernelCore& kernel);
+ ~KPageTableBase();
+
+ Result InitializeForKernel(bool is_64_bit, KVirtualAddress start, KVirtualAddress end,
+ Core::Memory::Memory& memory);
+ Result InitializeForProcess(Svc::CreateProcessFlag as_type, bool enable_aslr,
+ bool enable_device_address_space_merge, bool from_back,
+ KMemoryManager::Pool pool, KProcessAddress code_address,
+ size_t code_size, KSystemResource* system_resource,
+ KResourceLimit* resource_limit, Core::Memory::Memory& memory);
+
+ void Finalize();
+
+ bool IsKernel() const {
+ return m_is_kernel;
+ }
+ bool IsAslrEnabled() const {
+ return m_enable_aslr;
+ }
+
+ bool Contains(KProcessAddress addr) const {
+ return m_address_space_start <= addr && addr <= m_address_space_end - 1;
+ }
+
+ bool Contains(KProcessAddress addr, size_t size) const {
+ return m_address_space_start <= addr && addr < addr + size &&
+ addr + size - 1 <= m_address_space_end - 1;
+ }
+
+ bool IsInAliasRegion(KProcessAddress addr, size_t size) const {
+ return this->Contains(addr, size) && m_alias_region_start <= addr &&
+ addr + size - 1 <= m_alias_region_end - 1;
+ }
+
+ bool IsInHeapRegion(KProcessAddress addr, size_t size) const {
+ return this->Contains(addr, size) && m_heap_region_start <= addr &&
+ addr + size - 1 <= m_heap_region_end - 1;
+ }
+
+ bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const {
+ // Even though Unsafe physical memory is KMemoryState_Normal, it must be mapped inside the
+ // alias code region.
+ return this->CanContain(addr, size, Svc::MemoryState::AliasCode);
+ }
+
+ KScopedLightLock AcquireDeviceMapLock() {
+ return KScopedLightLock(m_device_map_lock);
+ }
+
+ KProcessAddress GetRegionAddress(Svc::MemoryState state) const;
+ size_t GetRegionSize(Svc::MemoryState state) const;
+ bool CanContain(KProcessAddress addr, size_t size, Svc::MemoryState state) const;
+
+ KProcessAddress GetRegionAddress(KMemoryState state) const {
+ return this->GetRegionAddress(static_cast<Svc::MemoryState>(state & KMemoryState::Mask));
+ }
+ size_t GetRegionSize(KMemoryState state) const {
+ return this->GetRegionSize(static_cast<Svc::MemoryState>(state & KMemoryState::Mask));
+ }
+ bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const {
+ return this->CanContain(addr, size,
+ static_cast<Svc::MemoryState>(state & KMemoryState::Mask));
+ }
+
+public:
+ Core::Memory::Memory& GetMemory() {
+ return *m_memory;
+ }
+
+ Core::Memory::Memory& GetMemory() const {
+ return *m_memory;
+ }
+
+ Common::PageTable& GetImpl() {
+ return *m_impl;
+ }
+
+ Common::PageTable& GetImpl() const {
+ return *m_impl;
+ }
+
+ size_t GetNumGuardPages() const {
+ return this->IsKernel() ? 1 : 4;
+ }
+
+protected:
+ // NOTE: These three functions (Operate, Operate, FinalizeUpdate) are virtual functions
+ // in Nintendo's kernel. We devirtualize them, since KPageTable is the only derived
+ // class, and this avoids unnecessary virtual function calls.
+ Result Operate(PageLinkedList* page_list, KProcessAddress virt_addr, size_t num_pages,
+ KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties,
+ OperationType operation, bool reuse_ll);
+ Result Operate(PageLinkedList* page_list, KProcessAddress virt_addr, size_t num_pages,
+ const KPageGroup& page_group, const KPageProperties properties,
+ OperationType operation, bool reuse_ll);
+ void FinalizeUpdate(PageLinkedList* page_list);
+
+ bool IsLockedByCurrentThread() const {
+ return m_general_lock.IsLockedByCurrentThread();
+ }
+
+ bool IsLinearMappedPhysicalAddress(KPhysicalAddress phys_addr) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ return m_kernel.MemoryLayout().IsLinearMappedPhysicalAddress(
+ m_cached_physical_linear_region, phys_addr);
+ }
+
+ bool IsLinearMappedPhysicalAddress(KPhysicalAddress phys_addr, size_t size) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ return m_kernel.MemoryLayout().IsLinearMappedPhysicalAddress(
+ m_cached_physical_linear_region, phys_addr, size);
+ }
+
+ bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ return m_kernel.MemoryLayout().IsHeapPhysicalAddress(m_cached_physical_heap_region,
+ phys_addr);
+ }
+
+ bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr, size_t size) {
+ ASSERT(this->IsLockedByCurrentThread());
+
+ return m_kernel.MemoryLayout().IsHeapPhysicalAddress(m_cached_physical_heap_region,
+ phys_addr, size);
+ }
+
+ bool IsHeapPhysicalAddressForFinalize(KPhysicalAddress phys_addr) {
+ ASSERT(!this->IsLockedByCurrentThread());
+
+ return m_kernel.MemoryLayout().IsHeapPhysicalAddress(m_cached_physical_heap_region,
+ phys_addr);
+ }
+
+ bool ContainsPages(KProcessAddress addr, size_t num_pages) const {
+ return (m_address_space_start <= addr) &&
+ (num_pages <= (m_address_space_end - m_address_space_start) / PageSize) &&
+ (addr + num_pages * PageSize - 1 <= m_address_space_end - 1);
+ }
+
+private:
+ KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages,
+ size_t num_pages, size_t alignment, size_t offset,
+ size_t guard_pages) const;
+
+ Result CheckMemoryStateContiguous(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
+ KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
+ Result CheckMemoryStateContiguous(KProcessAddress addr, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask,
+ KMemoryPermission perm, KMemoryAttribute attr_mask,
+ KMemoryAttribute attr) const {
+ R_RETURN(this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask,
+ perm, attr_mask, attr));
+ }
+
+ Result CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
+ Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
+ KMemoryAttribute* out_attr, size_t* out_blocks_needed,
+ KMemoryBlockManager::const_iterator it, KProcessAddress last_addr,
+ KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr,
+ KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const;
+ Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
+ KMemoryAttribute* out_attr, size_t* out_blocks_needed,
+ KProcessAddress addr, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr,
+ KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const;
+ Result CheckMemoryState(size_t* out_blocks_needed, KProcessAddress addr, size_t size,
+ KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr,
+ KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
+ R_RETURN(this->CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size,
+ state_mask, state, perm_mask, perm, attr_mask, attr,
+ ignore_attr));
+ }
+ Result CheckMemoryState(KProcessAddress addr, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr,
+ KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
+ R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm,
+ attr_mask, attr, ignore_attr));
+ }
+
+ Result LockMemoryAndOpen(KPageGroup* out_pg, KPhysicalAddress* out_paddr, KProcessAddress addr,
+ size_t size, KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr,
+ KMemoryPermission new_perm, KMemoryAttribute lock_attr);
+ Result UnlockMemory(KProcessAddress addr, size_t size, KMemoryState state_mask,
+ KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr,
+ KMemoryPermission new_perm, KMemoryAttribute lock_attr,
+ const KPageGroup* pg);
+
+ Result QueryInfoImpl(KMemoryInfo* out_info, Svc::PageInfo* out_page,
+ KProcessAddress address) const;
+
+ Result QueryMappingImpl(KProcessAddress* out, KPhysicalAddress address, size_t size,
+ Svc::MemoryState state) const;
+
+ Result AllocateAndMapPagesImpl(PageLinkedList* page_list, KProcessAddress address,
+ size_t num_pages, KMemoryPermission perm);
+ Result MapPageGroupImpl(PageLinkedList* page_list, KProcessAddress address,
+ const KPageGroup& pg, const KPageProperties properties, bool reuse_ll);
+
+ void RemapPageGroup(PageLinkedList* page_list, KProcessAddress address, size_t size,
+ const KPageGroup& pg);
+
+ Result MakePageGroup(KPageGroup& pg, KProcessAddress addr, size_t num_pages);
+ bool IsValidPageGroup(const KPageGroup& pg, KProcessAddress addr, size_t num_pages);
+
+ Result GetContiguousMemoryRangeWithState(MemoryRange* out, KProcessAddress address, size_t size,
+ KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr);
+
+ Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
+ KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start,
+ size_t region_num_pages, KMemoryState state, KMemoryPermission perm);
+
+ Result MapIoImpl(KProcessAddress* out, PageLinkedList* page_list, KPhysicalAddress phys_addr,
+ size_t size, KMemoryState state, KMemoryPermission perm);
+ Result ReadIoMemoryImpl(KProcessAddress dst_addr, KPhysicalAddress phys_addr, size_t size,
+ KMemoryState state);
+ Result WriteIoMemoryImpl(KPhysicalAddress phys_addr, KProcessAddress src_addr, size_t size,
+ KMemoryState state);
+
+ Result SetupForIpcClient(PageLinkedList* page_list, size_t* out_blocks_needed,
+ KProcessAddress address, size_t size, KMemoryPermission test_perm,
+ KMemoryState dst_state);
+ Result SetupForIpcServer(KProcessAddress* out_addr, size_t size, KProcessAddress src_addr,
+ KMemoryPermission test_perm, KMemoryState dst_state,
+ KPageTableBase& src_page_table, bool send);
+ void CleanupForIpcClientOnServerSetupFailure(PageLinkedList* page_list, KProcessAddress address,
+ size_t size, KMemoryPermission prot_perm);
+
+ size_t GetSize(KMemoryState state) const;
+
+ bool GetPhysicalAddressLocked(KPhysicalAddress* out, KProcessAddress virt_addr) const {
+ // Validate pre-conditions.
+ ASSERT(this->IsLockedByCurrentThread());
+
+ return this->GetImpl().GetPhysicalAddress(out, virt_addr);
+ }
+
+public:
+ bool GetPhysicalAddress(KPhysicalAddress* out, KProcessAddress virt_addr) const {
+ // Validate pre-conditions.
+ ASSERT(!this->IsLockedByCurrentThread());
+
+ // Acquire exclusive access to the table while doing address translation.
+ KScopedLightLock lk(m_general_lock);
+
+ return this->GetPhysicalAddressLocked(out, virt_addr);
+ }
+
+ KBlockInfoManager* GetBlockInfoManager() const {
+ return m_block_info_manager;
+ }
+
+ Result SetMemoryPermission(KProcessAddress addr, size_t size, Svc::MemoryPermission perm);
+ Result SetProcessMemoryPermission(KProcessAddress addr, size_t size,
+ Svc::MemoryPermission perm);
+ Result SetMemoryAttribute(KProcessAddress addr, size_t size, KMemoryAttribute mask,
+ KMemoryAttribute attr);
+ Result SetHeapSize(KProcessAddress* out, size_t size);
+ Result SetMaxHeapSize(size_t size);
+ Result QueryInfo(KMemoryInfo* out_info, Svc::PageInfo* out_page_info,
+ KProcessAddress addr) const;
+ Result QueryPhysicalAddress(Svc::lp64::PhysicalMemoryInfo* out, KProcessAddress address) const;
+ Result QueryStaticMapping(KProcessAddress* out, KPhysicalAddress address, size_t size) const {
+ R_RETURN(this->QueryMappingImpl(out, address, size, Svc::MemoryState::Static));
+ }
+ Result QueryIoMapping(KProcessAddress* out, KPhysicalAddress address, size_t size) const {
+ R_RETURN(this->QueryMappingImpl(out, address, size, Svc::MemoryState::Io));
+ }
+ Result MapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
+ Result UnmapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
+ Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
+ Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
+ Result MapIo(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm);
+ Result MapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size,
+ Svc::MemoryMapping mapping, Svc::MemoryPermission perm);
+ Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size,
+ Svc::MemoryMapping mapping);
+ Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm);
+ Result MapRegion(KMemoryRegionType region_type, KMemoryPermission perm);
+ Result MapInsecureMemory(KProcessAddress address, size_t size);
+ Result UnmapInsecureMemory(KProcessAddress address, size_t size);
+
+ Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
+ KPhysicalAddress phys_addr, KProcessAddress region_start,
+ size_t region_num_pages, KMemoryState state, KMemoryPermission perm) {
+ R_RETURN(this->MapPages(out_addr, num_pages, alignment, phys_addr, true, region_start,
+ region_num_pages, state, perm));
+ }
+
+ Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
+ KPhysicalAddress phys_addr, KMemoryState state, KMemoryPermission perm) {
+ R_RETURN(this->MapPages(out_addr, num_pages, alignment, phys_addr, true,
+ this->GetRegionAddress(state),
+ this->GetRegionSize(state) / PageSize, state, perm));
+ }
+
+ Result MapPages(KProcessAddress* out_addr, size_t num_pages, KMemoryState state,
+ KMemoryPermission perm) {
+ R_RETURN(this->MapPages(out_addr, num_pages, PageSize, 0, false,
+ this->GetRegionAddress(state),
+ this->GetRegionSize(state) / PageSize, state, perm));
+ }
+
+ Result MapPages(KProcessAddress address, size_t num_pages, KMemoryState state,
+ KMemoryPermission perm);
+ Result UnmapPages(KProcessAddress address, size_t num_pages, KMemoryState state);
+
+ Result MapPageGroup(KProcessAddress* out_addr, const KPageGroup& pg,
+ KProcessAddress region_start, size_t region_num_pages, KMemoryState state,
+ KMemoryPermission perm);
+ Result MapPageGroup(KProcessAddress address, const KPageGroup& pg, KMemoryState state,
+ KMemoryPermission perm);
+ Result UnmapPageGroup(KProcessAddress address, const KPageGroup& pg, KMemoryState state);
+
+ Result MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages,
+ KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr);
+
+ Result InvalidateProcessDataCache(KProcessAddress address, size_t size);
+ Result InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size);
+
+ Result ReadDebugMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
+ Result ReadDebugIoMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size,
+ KMemoryState state);
+
+ Result WriteDebugMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size);
+ Result WriteDebugIoMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size,
+ KMemoryState state);
+
+ Result LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address, size_t size,
+ KMemoryPermission perm, bool is_aligned, bool check_heap);
+ Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap);
+
+ Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size);
+ Result UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size);
+
+ Result OpenMemoryRangeForMapDeviceAddressSpace(KPageTableBase::MemoryRange* out,
+ KProcessAddress address, size_t size,
+ KMemoryPermission perm, bool is_aligned);
+ Result OpenMemoryRangeForUnmapDeviceAddressSpace(MemoryRange* out, KProcessAddress address,
+ size_t size);
+
+ Result LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address, size_t size);
+ Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size);
+
+ Result LockForTransferMemory(KPageGroup* out, KProcessAddress address, size_t size,
+ KMemoryPermission perm);
+ Result UnlockForTransferMemory(KProcessAddress address, size_t size, const KPageGroup& pg);
+ Result LockForCodeMemory(KPageGroup* out, KProcessAddress address, size_t size);
+ Result UnlockForCodeMemory(KProcessAddress address, size_t size, const KPageGroup& pg);
+
+ Result OpenMemoryRangeForProcessCacheOperation(MemoryRange* out, KProcessAddress address,
+ size_t size);
+
+ Result CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size,
+ KProcessAddress src_addr, KMemoryState src_state_mask,
+ KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr);
+ Result CopyMemoryFromLinearToKernel(void* buffer, size_t size, KProcessAddress src_addr,
+ KMemoryState src_state_mask, KMemoryState src_state,
+ KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr);
+ Result CopyMemoryFromUserToLinear(KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state,
+ KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr,
+ KProcessAddress src_addr);
+ Result CopyMemoryFromKernelToLinear(KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state,
+ KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr,
+ void* buffer);
+ Result CopyMemoryFromHeapToHeap(KPageTableBase& dst_page_table, KProcessAddress dst_addr,
+ size_t size, KMemoryState dst_state_mask,
+ KMemoryState dst_state, KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr,
+ KProcessAddress src_addr, KMemoryState src_state_mask,
+ KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr);
+ Result CopyMemoryFromHeapToHeapWithoutCheckDestination(
+ KPageTableBase& dst_page_table, KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state, KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr, KProcessAddress src_addr,
+ KMemoryState src_state_mask, KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr);
+
+ Result SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr,
+ KPageTableBase& src_page_table, KMemoryPermission test_perm,
+ KMemoryState dst_state, bool send);
+ Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state);
+ Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state);
+
+ Result MapPhysicalMemory(KProcessAddress address, size_t size);
+ Result UnmapPhysicalMemory(KProcessAddress address, size_t size);
+
+ Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
+ Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
+
+ Result UnmapProcessMemory(KProcessAddress dst_address, size_t size, KPageTableBase& src_pt,
+ KProcessAddress src_address);
+
+public:
+ KProcessAddress GetAddressSpaceStart() const {
+ return m_address_space_start;
+ }
+ KProcessAddress GetHeapRegionStart() const {
+ return m_heap_region_start;
+ }
+ KProcessAddress GetAliasRegionStart() const {
+ return m_alias_region_start;
+ }
+ KProcessAddress GetStackRegionStart() const {
+ return m_stack_region_start;
+ }
+ KProcessAddress GetKernelMapRegionStart() const {
+ return m_kernel_map_region_start;
+ }
+ KProcessAddress GetCodeRegionStart() const {
+ return m_code_region_start;
+ }
+ KProcessAddress GetAliasCodeRegionStart() const {
+ return m_alias_code_region_start;
+ }
+
+ size_t GetAddressSpaceSize() const {
+ return m_address_space_end - m_address_space_start;
+ }
+ size_t GetHeapRegionSize() const {
+ return m_heap_region_end - m_heap_region_start;
+ }
+ size_t GetAliasRegionSize() const {
+ return m_alias_region_end - m_alias_region_start;
+ }
+ size_t GetStackRegionSize() const {
+ return m_stack_region_end - m_stack_region_start;
+ }
+ size_t GetKernelMapRegionSize() const {
+ return m_kernel_map_region_end - m_kernel_map_region_start;
+ }
+ size_t GetCodeRegionSize() const {
+ return m_code_region_end - m_code_region_start;
+ }
+ size_t GetAliasCodeRegionSize() const {
+ return m_alias_code_region_end - m_alias_code_region_start;
+ }
+
+ size_t GetNormalMemorySize() const {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ return (m_current_heap_end - m_heap_region_start) + m_mapped_physical_memory_size;
+ }
+
+ size_t GetCodeSize() const;
+ size_t GetCodeDataSize() const;
+ size_t GetAliasCodeSize() const;
+ size_t GetAliasCodeDataSize() const;
+
+ u32 GetAllocateOption() const {
+ return m_allocate_option;
+ }
+
+ u32 GetAddressSpaceWidth() const {
+ return m_address_space_width;
+ }
+
+public:
+ // Linear mapped
+ static u8* GetLinearMappedVirtualPointer(KernelCore& kernel, KPhysicalAddress addr) {
+ return kernel.System().DeviceMemory().GetPointer<u8>(addr);
+ }
+
+ static KPhysicalAddress GetLinearMappedPhysicalAddress(KernelCore& kernel,
+ KVirtualAddress addr) {
+ return kernel.MemoryLayout().GetLinearPhysicalAddress(addr);
+ }
+
+ static KVirtualAddress GetLinearMappedVirtualAddress(KernelCore& kernel,
+ KPhysicalAddress addr) {
+ return kernel.MemoryLayout().GetLinearVirtualAddress(addr);
+ }
+
+ // Heap
+ static u8* GetHeapVirtualPointer(KernelCore& kernel, KPhysicalAddress addr) {
+ return kernel.System().DeviceMemory().GetPointer<u8>(addr);
+ }
+
+ static KPhysicalAddress GetHeapPhysicalAddress(KernelCore& kernel, KVirtualAddress addr) {
+ return GetLinearMappedPhysicalAddress(kernel, addr);
+ }
+
+ static KVirtualAddress GetHeapVirtualAddress(KernelCore& kernel, KPhysicalAddress addr) {
+ return GetLinearMappedVirtualAddress(kernel, addr);
+ }
+
+ // Member heap
+ u8* GetHeapVirtualPointer(KPhysicalAddress addr) {
+ return GetHeapVirtualPointer(m_kernel, addr);
+ }
+
+ KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress addr) {
+ return GetHeapPhysicalAddress(m_kernel, addr);
+ }
+
+ KVirtualAddress GetHeapVirtualAddress(KPhysicalAddress addr) {
+ return GetHeapVirtualAddress(m_kernel, addr);
+ }
+
+ // TODO: GetPageTableVirtualAddress
+ // TODO: GetPageTablePhysicalAddress
+};
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 1f4b0755d..3cfb414e5 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -298,9 +298,9 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
const bool enable_aslr = True(params.flags & Svc::CreateProcessFlag::EnableAslr);
const bool enable_das_merge =
False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
- R_TRY(m_page_table.InitializeForProcess(
- as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address,
- params.code_num_pages * PageSize, m_system_resource, res_limit, this->GetMemory()));
+ R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
+ params.code_address, params.code_num_pages * PageSize,
+ m_system_resource, res_limit, this->GetMemory()));
}
ON_RESULT_FAILURE_2 {
m_page_table.Finalize();
@@ -391,9 +391,9 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
const bool enable_aslr = True(params.flags & Svc::CreateProcessFlag::EnableAslr);
const bool enable_das_merge =
False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
- R_TRY(m_page_table.InitializeForProcess(as_type, enable_aslr, enable_das_merge,
- !enable_aslr, pool, params.code_address, code_size,
- m_system_resource, res_limit, this->GetMemory()));
+ R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
+ params.code_address, code_size, m_system_resource, res_limit,
+ this->GetMemory()));
}
ON_RESULT_FAILURE_2 {
m_page_table.Finalize();
@@ -1122,9 +1122,9 @@ Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_
void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
KProcess::KProcess(KernelCore& kernel)
- : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel.System()},
- m_state_lock{kernel}, m_list_lock{kernel}, m_cond_var{kernel.System()},
- m_address_arbiter{kernel.System()}, m_handle_table{kernel} {}
+ : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel},
+ m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
+ m_handle_table{kernel} {}
KProcess::~KProcess() = default;
Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index f9f755afa..8339465fd 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -5,13 +5,14 @@
#include <map>
+#include "core/file_sys/program_metadata.h"
#include "core/hle/kernel/code_set.h"
#include "core/hle/kernel/k_address_arbiter.h"
#include "core/hle/kernel/k_capabilities.h"
#include "core/hle/kernel/k_condition_variable.h"
#include "core/hle/kernel/k_handle_table.h"
-#include "core/hle/kernel/k_page_table.h"
#include "core/hle/kernel/k_page_table_manager.h"
+#include "core/hle/kernel/k_process_page_table.h"
#include "core/hle/kernel/k_system_resource.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_thread_local_page.h"
@@ -65,7 +66,7 @@ private:
using TLPIterator = TLPTree::iterator;
private:
- KPageTable m_page_table;
+ KProcessPageTable m_page_table;
std::atomic<size_t> m_used_kernel_memory_size{};
TLPTree m_fully_used_tlp_tree{};
TLPTree m_partially_used_tlp_tree{};
@@ -254,9 +255,8 @@ public:
return m_is_hbl;
}
- Kernel::KMemoryManager::Direction GetAllocateOption() const {
- // TODO: property of the KPageTableBase
- return KMemoryManager::Direction::FromFront;
+ u32 GetAllocateOption() const {
+ return m_page_table.GetAllocateOption();
}
ThreadList& GetThreadList() {
@@ -295,10 +295,10 @@ public:
return m_list_lock;
}
- KPageTable& GetPageTable() {
+ KProcessPageTable& GetPageTable() {
return m_page_table;
}
- const KPageTable& GetPageTable() const {
+ const KProcessPageTable& GetPageTable() const {
return m_page_table;
}
diff --git a/src/core/hle/kernel/k_process_page_table.h b/src/core/hle/kernel/k_process_page_table.h
new file mode 100644
index 000000000..b7ae5abd0
--- /dev/null
+++ b/src/core/hle/kernel/k_process_page_table.h
@@ -0,0 +1,480 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/kernel/k_page_table.h"
+#include "core/hle/kernel/k_scoped_lock.h"
+#include "core/hle/kernel/svc_types.h"
+
+namespace Core {
+class ARM_Interface;
+}
+
+namespace Kernel {
+
+class KProcessPageTable {
+private:
+ KPageTable m_page_table;
+
+public:
+ KProcessPageTable(KernelCore& kernel) : m_page_table(kernel) {}
+
+ Result Initialize(Svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge,
+ bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address,
+ size_t code_size, KSystemResource* system_resource,
+ KResourceLimit* resource_limit, Core::Memory::Memory& memory) {
+ R_RETURN(m_page_table.InitializeForProcess(as_type, enable_aslr, enable_das_merge,
+ from_back, pool, code_address, code_size,
+ system_resource, resource_limit, memory));
+ }
+
+ void Finalize() {
+ m_page_table.Finalize();
+ }
+
+ Core::Memory::Memory& GetMemory() {
+ return m_page_table.GetMemory();
+ }
+
+ Core::Memory::Memory& GetMemory() const {
+ return m_page_table.GetMemory();
+ }
+
+ Common::PageTable& GetImpl() {
+ return m_page_table.GetImpl();
+ }
+
+ Common::PageTable& GetImpl() const {
+ return m_page_table.GetImpl();
+ }
+
+ size_t GetNumGuardPages() const {
+ return m_page_table.GetNumGuardPages();
+ }
+
+ KScopedLightLock AcquireDeviceMapLock() {
+ return m_page_table.AcquireDeviceMapLock();
+ }
+
+ Result SetMemoryPermission(KProcessAddress addr, size_t size, Svc::MemoryPermission perm) {
+ R_RETURN(m_page_table.SetMemoryPermission(addr, size, perm));
+ }
+
+ Result SetProcessMemoryPermission(KProcessAddress addr, size_t size,
+ Svc::MemoryPermission perm) {
+ R_RETURN(m_page_table.SetProcessMemoryPermission(addr, size, perm));
+ }
+
+ Result SetMemoryAttribute(KProcessAddress addr, size_t size, KMemoryAttribute mask,
+ KMemoryAttribute attr) {
+ R_RETURN(m_page_table.SetMemoryAttribute(addr, size, mask, attr));
+ }
+
+ Result SetHeapSize(KProcessAddress* out, size_t size) {
+ R_RETURN(m_page_table.SetHeapSize(out, size));
+ }
+
+ Result SetMaxHeapSize(size_t size) {
+ R_RETURN(m_page_table.SetMaxHeapSize(size));
+ }
+
+ Result QueryInfo(KMemoryInfo* out_info, Svc::PageInfo* out_page_info,
+ KProcessAddress addr) const {
+ R_RETURN(m_page_table.QueryInfo(out_info, out_page_info, addr));
+ }
+
+ Result QueryPhysicalAddress(Svc::lp64::PhysicalMemoryInfo* out, KProcessAddress address) {
+ R_RETURN(m_page_table.QueryPhysicalAddress(out, address));
+ }
+
+ Result QueryStaticMapping(KProcessAddress* out, KPhysicalAddress address, size_t size) {
+ R_RETURN(m_page_table.QueryStaticMapping(out, address, size));
+ }
+
+ Result QueryIoMapping(KProcessAddress* out, KPhysicalAddress address, size_t size) {
+ R_RETURN(m_page_table.QueryIoMapping(out, address, size));
+ }
+
+ Result MapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size) {
+ R_RETURN(m_page_table.MapMemory(dst_address, src_address, size));
+ }
+
+ Result UnmapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size) {
+ R_RETURN(m_page_table.UnmapMemory(dst_address, src_address, size));
+ }
+
+ Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size) {
+ R_RETURN(m_page_table.MapCodeMemory(dst_address, src_address, size));
+ }
+
+ Result UnmapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size) {
+ R_RETURN(m_page_table.UnmapCodeMemory(dst_address, src_address, size));
+ }
+
+ Result MapIo(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) {
+ R_RETURN(m_page_table.MapIo(phys_addr, size, perm));
+ }
+
+ Result MapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size,
+ Svc::MemoryMapping mapping, Svc::MemoryPermission perm) {
+ R_RETURN(m_page_table.MapIoRegion(dst_address, phys_addr, size, mapping, perm));
+ }
+
+ Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size,
+ Svc::MemoryMapping mapping) {
+ R_RETURN(m_page_table.UnmapIoRegion(dst_address, phys_addr, size, mapping));
+ }
+
+ Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) {
+ R_RETURN(m_page_table.MapStatic(phys_addr, size, perm));
+ }
+
+ Result MapRegion(KMemoryRegionType region_type, KMemoryPermission perm) {
+ R_RETURN(m_page_table.MapRegion(region_type, perm));
+ }
+
+ Result MapInsecureMemory(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.MapInsecureMemory(address, size));
+ }
+
+ Result UnmapInsecureMemory(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.UnmapInsecureMemory(address, size));
+ }
+
+ Result MapPageGroup(KProcessAddress addr, const KPageGroup& pg, KMemoryState state,
+ KMemoryPermission perm) {
+ R_RETURN(m_page_table.MapPageGroup(addr, pg, state, perm));
+ }
+
+ Result UnmapPageGroup(KProcessAddress address, const KPageGroup& pg, KMemoryState state) {
+ R_RETURN(m_page_table.UnmapPageGroup(address, pg, state));
+ }
+
+ Result MapPages(KProcessAddress* out_addr, size_t num_pages, size_t alignment,
+ KPhysicalAddress phys_addr, KMemoryState state, KMemoryPermission perm) {
+ R_RETURN(m_page_table.MapPages(out_addr, num_pages, alignment, phys_addr, state, perm));
+ }
+
+ Result MapPages(KProcessAddress* out_addr, size_t num_pages, KMemoryState state,
+ KMemoryPermission perm) {
+ R_RETURN(m_page_table.MapPages(out_addr, num_pages, state, perm));
+ }
+
+ Result MapPages(KProcessAddress address, size_t num_pages, KMemoryState state,
+ KMemoryPermission perm) {
+ R_RETURN(m_page_table.MapPages(address, num_pages, state, perm));
+ }
+
+ Result UnmapPages(KProcessAddress addr, size_t num_pages, KMemoryState state) {
+ R_RETURN(m_page_table.UnmapPages(addr, num_pages, state));
+ }
+
+ Result MakeAndOpenPageGroup(KPageGroup* out, KProcessAddress address, size_t num_pages,
+ KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask, KMemoryAttribute attr) {
+ R_RETURN(m_page_table.MakeAndOpenPageGroup(out, address, num_pages, state_mask, state,
+ perm_mask, perm, attr_mask, attr));
+ }
+
+ Result InvalidateProcessDataCache(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.InvalidateProcessDataCache(address, size));
+ }
+
+ Result ReadDebugMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size) {
+ R_RETURN(m_page_table.ReadDebugMemory(dst_address, src_address, size));
+ }
+
+ Result ReadDebugIoMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size,
+ KMemoryState state) {
+ R_RETURN(m_page_table.ReadDebugIoMemory(dst_address, src_address, size, state));
+ }
+
+ Result WriteDebugMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size) {
+ R_RETURN(m_page_table.WriteDebugMemory(dst_address, src_address, size));
+ }
+
+ Result WriteDebugIoMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size,
+ KMemoryState state) {
+ R_RETURN(m_page_table.WriteDebugIoMemory(dst_address, src_address, size, state));
+ }
+
+ Result LockForMapDeviceAddressSpace(bool* out_is_io, KProcessAddress address, size_t size,
+ KMemoryPermission perm, bool is_aligned, bool check_heap) {
+ R_RETURN(m_page_table.LockForMapDeviceAddressSpace(out_is_io, address, size, perm,
+ is_aligned, check_heap));
+ }
+
+ Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap) {
+ R_RETURN(m_page_table.LockForUnmapDeviceAddressSpace(address, size, check_heap));
+ }
+
+ Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.UnlockForDeviceAddressSpace(address, size));
+ }
+
+ Result UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.UnlockForDeviceAddressSpacePartialMap(address, size));
+ }
+
+ Result OpenMemoryRangeForMapDeviceAddressSpace(KPageTableBase::MemoryRange* out,
+ KProcessAddress address, size_t size,
+ KMemoryPermission perm, bool is_aligned) {
+ R_RETURN(m_page_table.OpenMemoryRangeForMapDeviceAddressSpace(out, address, size, perm,
+ is_aligned));
+ }
+
+ Result OpenMemoryRangeForUnmapDeviceAddressSpace(KPageTableBase::MemoryRange* out,
+ KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.OpenMemoryRangeForUnmapDeviceAddressSpace(out, address, size));
+ }
+
+ Result LockForIpcUserBuffer(KPhysicalAddress* out, KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.LockForIpcUserBuffer(out, address, size));
+ }
+
+ Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.UnlockForIpcUserBuffer(address, size));
+ }
+
+ Result LockForTransferMemory(KPageGroup* out, KProcessAddress address, size_t size,
+ KMemoryPermission perm) {
+ R_RETURN(m_page_table.LockForTransferMemory(out, address, size, perm));
+ }
+
+ Result UnlockForTransferMemory(KProcessAddress address, size_t size, const KPageGroup& pg) {
+ R_RETURN(m_page_table.UnlockForTransferMemory(address, size, pg));
+ }
+
+ Result LockForCodeMemory(KPageGroup* out, KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.LockForCodeMemory(out, address, size));
+ }
+
+ Result UnlockForCodeMemory(KProcessAddress address, size_t size, const KPageGroup& pg) {
+ R_RETURN(m_page_table.UnlockForCodeMemory(address, size, pg));
+ }
+
+ Result OpenMemoryRangeForProcessCacheOperation(KPageTableBase::MemoryRange* out,
+ KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.OpenMemoryRangeForProcessCacheOperation(out, address, size));
+ }
+
+ Result CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size,
+ KProcessAddress src_addr, KMemoryState src_state_mask,
+ KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr) {
+ R_RETURN(m_page_table.CopyMemoryFromLinearToUser(dst_addr, size, src_addr, src_state_mask,
+ src_state, src_test_perm, src_attr_mask,
+ src_attr));
+ }
+
+ Result CopyMemoryFromLinearToKernel(void* dst_addr, size_t size, KProcessAddress src_addr,
+ KMemoryState src_state_mask, KMemoryState src_state,
+ KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr) {
+ R_RETURN(m_page_table.CopyMemoryFromLinearToKernel(dst_addr, size, src_addr, src_state_mask,
+ src_state, src_test_perm, src_attr_mask,
+ src_attr));
+ }
+
+ Result CopyMemoryFromUserToLinear(KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state,
+ KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr,
+ KProcessAddress src_addr) {
+ R_RETURN(m_page_table.CopyMemoryFromUserToLinear(dst_addr, size, dst_state_mask, dst_state,
+ dst_test_perm, dst_attr_mask, dst_attr,
+ src_addr));
+ }
+
+ Result CopyMemoryFromKernelToLinear(KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state,
+ KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr,
+ void* src_addr) {
+ R_RETURN(m_page_table.CopyMemoryFromKernelToLinear(dst_addr, size, dst_state_mask,
+ dst_state, dst_test_perm, dst_attr_mask,
+ dst_attr, src_addr));
+ }
+
+ Result CopyMemoryFromHeapToHeap(KProcessPageTable& dst_page_table, KProcessAddress dst_addr,
+ size_t size, KMemoryState dst_state_mask,
+ KMemoryState dst_state, KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr,
+ KProcessAddress src_addr, KMemoryState src_state_mask,
+ KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr) {
+ R_RETURN(m_page_table.CopyMemoryFromHeapToHeap(
+ dst_page_table.m_page_table, dst_addr, size, dst_state_mask, dst_state, dst_test_perm,
+ dst_attr_mask, dst_attr, src_addr, src_state_mask, src_state, src_test_perm,
+ src_attr_mask, src_attr));
+ }
+
+ Result CopyMemoryFromHeapToHeapWithoutCheckDestination(
+ KProcessPageTable& dst_page_table, KProcessAddress dst_addr, size_t size,
+ KMemoryState dst_state_mask, KMemoryState dst_state, KMemoryPermission dst_test_perm,
+ KMemoryAttribute dst_attr_mask, KMemoryAttribute dst_attr, KProcessAddress src_addr,
+ KMemoryState src_state_mask, KMemoryState src_state, KMemoryPermission src_test_perm,
+ KMemoryAttribute src_attr_mask, KMemoryAttribute src_attr) {
+ R_RETURN(m_page_table.CopyMemoryFromHeapToHeapWithoutCheckDestination(
+ dst_page_table.m_page_table, dst_addr, size, dst_state_mask, dst_state, dst_test_perm,
+ dst_attr_mask, dst_attr, src_addr, src_state_mask, src_state, src_test_perm,
+ src_attr_mask, src_attr));
+ }
+
+ Result SetupForIpc(KProcessAddress* out_dst_addr, size_t size, KProcessAddress src_addr,
+ KProcessPageTable& src_page_table, KMemoryPermission test_perm,
+ KMemoryState dst_state, bool send) {
+ R_RETURN(m_page_table.SetupForIpc(out_dst_addr, size, src_addr, src_page_table.m_page_table,
+ test_perm, dst_state, send));
+ }
+
+ Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state) {
+ R_RETURN(m_page_table.CleanupForIpcServer(address, size, dst_state));
+ }
+
+ Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state) {
+ R_RETURN(m_page_table.CleanupForIpcClient(address, size, dst_state));
+ }
+
+ Result MapPhysicalMemory(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.MapPhysicalMemory(address, size));
+ }
+
+ Result UnmapPhysicalMemory(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.UnmapPhysicalMemory(address, size));
+ }
+
+ Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.MapPhysicalMemoryUnsafe(address, size));
+ }
+
+ Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size) {
+ R_RETURN(m_page_table.UnmapPhysicalMemoryUnsafe(address, size));
+ }
+
+ Result UnmapProcessMemory(KProcessAddress dst_address, size_t size,
+ KProcessPageTable& src_page_table, KProcessAddress src_address) {
+ R_RETURN(m_page_table.UnmapProcessMemory(dst_address, size, src_page_table.m_page_table,
+ src_address));
+ }
+
+ bool GetPhysicalAddress(KPhysicalAddress* out, KProcessAddress address) {
+ return m_page_table.GetPhysicalAddress(out, address);
+ }
+
+ bool Contains(KProcessAddress addr, size_t size) const {
+ return m_page_table.Contains(addr, size);
+ }
+
+ bool IsInAliasRegion(KProcessAddress addr, size_t size) const {
+ return m_page_table.IsInAliasRegion(addr, size);
+ }
+ bool IsInHeapRegion(KProcessAddress addr, size_t size) const {
+ return m_page_table.IsInHeapRegion(addr, size);
+ }
+ bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const {
+ return m_page_table.IsInUnsafeAliasRegion(addr, size);
+ }
+
+ bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const {
+ return m_page_table.CanContain(addr, size, state);
+ }
+
+ KProcessAddress GetAddressSpaceStart() const {
+ return m_page_table.GetAddressSpaceStart();
+ }
+ KProcessAddress GetHeapRegionStart() const {
+ return m_page_table.GetHeapRegionStart();
+ }
+ KProcessAddress GetAliasRegionStart() const {
+ return m_page_table.GetAliasRegionStart();
+ }
+ KProcessAddress GetStackRegionStart() const {
+ return m_page_table.GetStackRegionStart();
+ }
+ KProcessAddress GetKernelMapRegionStart() const {
+ return m_page_table.GetKernelMapRegionStart();
+ }
+ KProcessAddress GetCodeRegionStart() const {
+ return m_page_table.GetCodeRegionStart();
+ }
+ KProcessAddress GetAliasCodeRegionStart() const {
+ return m_page_table.GetAliasCodeRegionStart();
+ }
+
+ size_t GetAddressSpaceSize() const {
+ return m_page_table.GetAddressSpaceSize();
+ }
+ size_t GetHeapRegionSize() const {
+ return m_page_table.GetHeapRegionSize();
+ }
+ size_t GetAliasRegionSize() const {
+ return m_page_table.GetAliasRegionSize();
+ }
+ size_t GetStackRegionSize() const {
+ return m_page_table.GetStackRegionSize();
+ }
+ size_t GetKernelMapRegionSize() const {
+ return m_page_table.GetKernelMapRegionSize();
+ }
+ size_t GetCodeRegionSize() const {
+ return m_page_table.GetCodeRegionSize();
+ }
+ size_t GetAliasCodeRegionSize() const {
+ return m_page_table.GetAliasCodeRegionSize();
+ }
+
+ size_t GetNormalMemorySize() const {
+ return m_page_table.GetNormalMemorySize();
+ }
+
+ size_t GetCodeSize() const {
+ return m_page_table.GetCodeSize();
+ }
+ size_t GetCodeDataSize() const {
+ return m_page_table.GetCodeDataSize();
+ }
+
+ size_t GetAliasCodeSize() const {
+ return m_page_table.GetAliasCodeSize();
+ }
+ size_t GetAliasCodeDataSize() const {
+ return m_page_table.GetAliasCodeDataSize();
+ }
+
+ u32 GetAllocateOption() const {
+ return m_page_table.GetAllocateOption();
+ }
+
+ u32 GetAddressSpaceWidth() const {
+ return m_page_table.GetAddressSpaceWidth();
+ }
+
+ KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) {
+ return m_page_table.GetHeapPhysicalAddress(address);
+ }
+
+ u8* GetHeapVirtualPointer(KPhysicalAddress address) {
+ return m_page_table.GetHeapVirtualPointer(address);
+ }
+
+ KVirtualAddress GetHeapVirtualAddress(KPhysicalAddress address) {
+ return m_page_table.GetHeapVirtualAddress(address);
+ }
+
+ KBlockInfoManager* GetBlockInfoManager() {
+ return m_page_table.GetBlockInfoManager();
+ }
+
+ KPageTable& GetBasePageTable() {
+ return m_page_table;
+ }
+
+ const KPageTable& GetBasePageTable() const {
+ return m_page_table;
+ }
+};
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index c64ceb530..3ea653163 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -383,7 +383,7 @@ Result KServerSession::SendReply(bool is_hle) {
if (event != nullptr) {
// // Get the client process/page table.
// KProcess *client_process = client_thread->GetOwnerProcess();
- // KPageTable *client_page_table = std::addressof(client_process->PageTable());
+ // KProcessPageTable *client_page_table = std::addressof(client_process->PageTable());
// // If we need to, reply with an async error.
// if (R_FAILED(client_result)) {
diff --git a/src/core/hle/kernel/k_system_resource.cpp b/src/core/hle/kernel/k_system_resource.cpp
index 07e92aa80..b51941faf 100644
--- a/src/core/hle/kernel/k_system_resource.cpp
+++ b/src/core/hle/kernel/k_system_resource.cpp
@@ -40,7 +40,7 @@ Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_l
// Get resource pointer.
KPhysicalAddress resource_paddr =
- KPageTable::GetHeapPhysicalAddress(m_kernel.MemoryLayout(), m_resource_address);
+ KPageTable::GetHeapPhysicalAddress(m_kernel, m_resource_address);
auto* resource =
m_kernel.System().DeviceMemory().GetPointer<KPageTableManager::RefCount>(resource_paddr);
diff --git a/src/core/hle/kernel/k_thread_local_page.cpp b/src/core/hle/kernel/k_thread_local_page.cpp
index 2c45b4232..a632d1634 100644
--- a/src/core/hle/kernel/k_thread_local_page.cpp
+++ b/src/core/hle/kernel/k_thread_local_page.cpp
@@ -37,8 +37,8 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) {
Result KThreadLocalPage::Finalize() {
// Get the physical address of the page.
- const KPhysicalAddress phys_addr = m_owner->GetPageTable().GetPhysicalAddr(m_virt_addr);
- ASSERT(phys_addr);
+ KPhysicalAddress phys_addr{};
+ ASSERT(m_owner->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), m_virt_addr));
// Unmap the page.
R_TRY(m_owner->GetPageTable().UnmapPages(this->GetAddress(), 1, KMemoryState::ThreadLocal));
diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp
deleted file mode 100644
index 773319ad8..000000000
--- a/src/core/hle/kernel/process_capability.cpp
+++ /dev/null
@@ -1,389 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <bit>
-
-#include "common/bit_util.h"
-#include "common/logging/log.h"
-#include "core/hle/kernel/k_handle_table.h"
-#include "core/hle/kernel/k_page_table.h"
-#include "core/hle/kernel/process_capability.h"
-#include "core/hle/kernel/svc_results.h"
-
-namespace Kernel {
-namespace {
-
-// clang-format off
-
-// Shift offsets for kernel capability types.
-enum : u32 {
- CapabilityOffset_PriorityAndCoreNum = 3,
- CapabilityOffset_Syscall = 4,
- CapabilityOffset_MapPhysical = 6,
- CapabilityOffset_MapIO = 7,
- CapabilityOffset_MapRegion = 10,
- CapabilityOffset_Interrupt = 11,
- CapabilityOffset_ProgramType = 13,
- CapabilityOffset_KernelVersion = 14,
- CapabilityOffset_HandleTableSize = 15,
- CapabilityOffset_Debug = 16,
-};
-
-// Combined mask of all parameters that may be initialized only once.
-constexpr u32 InitializeOnceMask = (1U << CapabilityOffset_PriorityAndCoreNum) |
- (1U << CapabilityOffset_ProgramType) |
- (1U << CapabilityOffset_KernelVersion) |
- (1U << CapabilityOffset_HandleTableSize) |
- (1U << CapabilityOffset_Debug);
-
-// Packed kernel version indicating 10.4.0
-constexpr u32 PackedKernelVersion = 0x520000;
-
-// Indicates possible types of capabilities that can be specified.
-enum class CapabilityType : u32 {
- Unset = 0U,
- PriorityAndCoreNum = (1U << CapabilityOffset_PriorityAndCoreNum) - 1,
- Syscall = (1U << CapabilityOffset_Syscall) - 1,
- MapPhysical = (1U << CapabilityOffset_MapPhysical) - 1,
- MapIO = (1U << CapabilityOffset_MapIO) - 1,
- MapRegion = (1U << CapabilityOffset_MapRegion) - 1,
- Interrupt = (1U << CapabilityOffset_Interrupt) - 1,
- ProgramType = (1U << CapabilityOffset_ProgramType) - 1,
- KernelVersion = (1U << CapabilityOffset_KernelVersion) - 1,
- HandleTableSize = (1U << CapabilityOffset_HandleTableSize) - 1,
- Debug = (1U << CapabilityOffset_Debug) - 1,
- Ignorable = 0xFFFFFFFFU,
-};
-
-// clang-format on
-
-constexpr CapabilityType GetCapabilityType(u32 value) {
- return static_cast<CapabilityType>((~value & (value + 1)) - 1);
-}
-
-u32 GetFlagBitOffset(CapabilityType type) {
- const auto value = static_cast<u32>(type);
- return static_cast<u32>(Common::BitSize<u32>() - static_cast<u32>(std::countl_zero(value)));
-}
-
-} // Anonymous namespace
-
-Result ProcessCapabilities::InitializeForKernelProcess(const u32* capabilities,
- std::size_t num_capabilities,
- KPageTable& page_table) {
- Clear();
-
- // Allow all cores and priorities.
- core_mask = 0xF;
- priority_mask = 0xFFFFFFFFFFFFFFFF;
- kernel_version = PackedKernelVersion;
-
- return ParseCapabilities(capabilities, num_capabilities, page_table);
-}
-
-Result ProcessCapabilities::InitializeForUserProcess(const u32* capabilities,
- std::size_t num_capabilities,
- KPageTable& page_table) {
- Clear();
-
- return ParseCapabilities(capabilities, num_capabilities, page_table);
-}
-
-void ProcessCapabilities::InitializeForMetadatalessProcess() {
- // Allow all cores and priorities
- core_mask = 0xF;
- priority_mask = 0xFFFFFFFFFFFFFFFF;
- kernel_version = PackedKernelVersion;
-
- // Allow all system calls and interrupts.
- svc_capabilities.set();
- interrupt_capabilities.set();
-
- // Allow using the maximum possible amount of handles
- handle_table_size = static_cast<s32>(KHandleTable::MaxTableSize);
-
- // Allow all debugging capabilities.
- is_debuggable = true;
- can_force_debug = true;
-}
-
-Result ProcessCapabilities::ParseCapabilities(const u32* capabilities, std::size_t num_capabilities,
- KPageTable& page_table) {
- u32 set_flags = 0;
- u32 set_svc_bits = 0;
-
- for (std::size_t i = 0; i < num_capabilities; ++i) {
- const u32 descriptor = capabilities[i];
- const auto type = GetCapabilityType(descriptor);
-
- if (type == CapabilityType::MapPhysical) {
- i++;
-
- // The MapPhysical type uses two descriptor flags for its parameters.
- // If there's only one, then there's a problem.
- if (i >= num_capabilities) {
- LOG_ERROR(Kernel, "Invalid combination! i={}", i);
- return ResultInvalidCombination;
- }
-
- const auto size_flags = capabilities[i];
- if (GetCapabilityType(size_flags) != CapabilityType::MapPhysical) {
- LOG_ERROR(Kernel, "Invalid capability type! size_flags={}", size_flags);
- return ResultInvalidCombination;
- }
-
- const auto result = HandleMapPhysicalFlags(descriptor, size_flags, page_table);
- if (result.IsError()) {
- LOG_ERROR(Kernel, "Failed to map physical flags! descriptor={}, size_flags={}",
- descriptor, size_flags);
- return result;
- }
- } else {
- const auto result =
- ParseSingleFlagCapability(set_flags, set_svc_bits, descriptor, page_table);
- if (result.IsError()) {
- LOG_ERROR(
- Kernel,
- "Failed to parse capability flag! set_flags={}, set_svc_bits={}, descriptor={}",
- set_flags, set_svc_bits, descriptor);
- return result;
- }
- }
- }
-
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag,
- KPageTable& page_table) {
- const auto type = GetCapabilityType(flag);
-
- if (type == CapabilityType::Unset) {
- return ResultInvalidArgument;
- }
-
- // Bail early on ignorable entries, as one would expect,
- // ignorable descriptors can be ignored.
- if (type == CapabilityType::Ignorable) {
- return ResultSuccess;
- }
-
- // Ensure that the give flag hasn't already been initialized before.
- // If it has been, then bail.
- const u32 flag_length = GetFlagBitOffset(type);
- const u32 set_flag = 1U << flag_length;
- if ((set_flag & set_flags & InitializeOnceMask) != 0) {
- LOG_ERROR(Kernel,
- "Attempted to initialize flags that may only be initialized once. set_flags={}",
- set_flags);
- return ResultInvalidCombination;
- }
- set_flags |= set_flag;
-
- switch (type) {
- case CapabilityType::PriorityAndCoreNum:
- return HandlePriorityCoreNumFlags(flag);
- case CapabilityType::Syscall:
- return HandleSyscallFlags(set_svc_bits, flag);
- case CapabilityType::MapIO:
- return HandleMapIOFlags(flag, page_table);
- case CapabilityType::MapRegion:
- return HandleMapRegionFlags(flag, page_table);
- case CapabilityType::Interrupt:
- return HandleInterruptFlags(flag);
- case CapabilityType::ProgramType:
- return HandleProgramTypeFlags(flag);
- case CapabilityType::KernelVersion:
- return HandleKernelVersionFlags(flag);
- case CapabilityType::HandleTableSize:
- return HandleHandleTableFlags(flag);
- case CapabilityType::Debug:
- return HandleDebugFlags(flag);
- default:
- break;
- }
-
- LOG_ERROR(Kernel, "Invalid capability type! type={}", type);
- return ResultInvalidArgument;
-}
-
-void ProcessCapabilities::Clear() {
- svc_capabilities.reset();
- interrupt_capabilities.reset();
-
- core_mask = 0;
- priority_mask = 0;
-
- handle_table_size = 0;
- kernel_version = 0;
-
- program_type = ProgramType::SysModule;
-
- is_debuggable = false;
- can_force_debug = false;
-}
-
-Result ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) {
- if (priority_mask != 0 || core_mask != 0) {
- LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}",
- priority_mask, core_mask);
- return ResultInvalidArgument;
- }
-
- const u32 core_num_min = (flags >> 16) & 0xFF;
- const u32 core_num_max = (flags >> 24) & 0xFF;
- if (core_num_min > core_num_max) {
- LOG_ERROR(Kernel, "Core min is greater than core max! core_num_min={}, core_num_max={}",
- core_num_min, core_num_max);
- return ResultInvalidCombination;
- }
-
- const u32 priority_min = (flags >> 10) & 0x3F;
- const u32 priority_max = (flags >> 4) & 0x3F;
- if (priority_min > priority_max) {
- LOG_ERROR(Kernel,
- "Priority min is greater than priority max! priority_min={}, priority_max={}",
- core_num_min, priority_max);
- return ResultInvalidCombination;
- }
-
- // The switch only has 4 usable cores.
- if (core_num_max >= 4) {
- LOG_ERROR(Kernel, "Invalid max cores specified! core_num_max={}", core_num_max);
- return ResultInvalidCoreId;
- }
-
- const auto make_mask = [](u64 min, u64 max) {
- const u64 range = max - min + 1;
- const u64 mask = (1ULL << range) - 1;
-
- return mask << min;
- };
-
- core_mask = make_mask(core_num_min, core_num_max);
- priority_mask = make_mask(priority_min, priority_max);
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags) {
- const u32 index = flags >> 29;
- const u32 svc_bit = 1U << index;
-
- // If we've already set this svc before, bail.
- if ((set_svc_bits & svc_bit) != 0) {
- return ResultInvalidCombination;
- }
- set_svc_bits |= svc_bit;
-
- const u32 svc_mask = (flags >> 5) & 0xFFFFFF;
- for (u32 i = 0; i < 24; ++i) {
- const u32 svc_number = index * 24 + i;
-
- if ((svc_mask & (1U << i)) == 0) {
- continue;
- }
-
- svc_capabilities[svc_number] = true;
- }
-
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleMapPhysicalFlags(u32 flags, u32 size_flags,
- KPageTable& page_table) {
- // TODO(Lioncache): Implement once the memory manager can handle this.
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleMapIOFlags(u32 flags, KPageTable& page_table) {
- // TODO(Lioncache): Implement once the memory manager can handle this.
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleMapRegionFlags(u32 flags, KPageTable& page_table) {
- // TODO(Lioncache): Implement once the memory manager can handle this.
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleInterruptFlags(u32 flags) {
- constexpr u32 interrupt_ignore_value = 0x3FF;
- const u32 interrupt0 = (flags >> 12) & 0x3FF;
- const u32 interrupt1 = (flags >> 22) & 0x3FF;
-
- for (u32 interrupt : {interrupt0, interrupt1}) {
- if (interrupt == interrupt_ignore_value) {
- continue;
- }
-
- // NOTE:
- // This should be checking a generic interrupt controller value
- // as part of the calculation, however, given we don't currently
- // emulate that, it's sufficient to mark every interrupt as defined.
-
- if (interrupt >= interrupt_capabilities.size()) {
- LOG_ERROR(Kernel, "Process interrupt capability is out of range! svc_number={}",
- interrupt);
- return ResultOutOfRange;
- }
-
- interrupt_capabilities[interrupt] = true;
- }
-
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleProgramTypeFlags(u32 flags) {
- const u32 reserved = flags >> 17;
- if (reserved != 0) {
- LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
- return ResultReservedUsed;
- }
-
- program_type = static_cast<ProgramType>((flags >> 14) & 0b111);
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleKernelVersionFlags(u32 flags) {
- // Yes, the internal member variable is checked in the actual kernel here.
- // This might look odd for options that are only allowed to be initialized
- // just once, however the kernel has a separate initialization function for
- // kernel processes and userland processes. The kernel variant sets this
- // member variable ahead of time.
-
- const u32 major_version = kernel_version >> 19;
-
- if (major_version != 0 || flags < 0x80000) {
- LOG_ERROR(Kernel,
- "Kernel version is non zero or flags are too small! major_version={}, flags={}",
- major_version, flags);
- return ResultInvalidArgument;
- }
-
- kernel_version = flags;
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleHandleTableFlags(u32 flags) {
- const u32 reserved = flags >> 26;
- if (reserved != 0) {
- LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
- return ResultReservedUsed;
- }
-
- handle_table_size = static_cast<s32>((flags >> 16) & 0x3FF);
- return ResultSuccess;
-}
-
-Result ProcessCapabilities::HandleDebugFlags(u32 flags) {
- const u32 reserved = flags >> 19;
- if (reserved != 0) {
- LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
- return ResultReservedUsed;
- }
-
- is_debuggable = (flags & 0x20000) != 0;
- can_force_debug = (flags & 0x40000) != 0;
- return ResultSuccess;
-}
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/process_capability.h b/src/core/hle/kernel/process_capability.h
deleted file mode 100644
index ff05dc5ff..000000000
--- a/src/core/hle/kernel/process_capability.h
+++ /dev/null
@@ -1,266 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <bitset>
-
-#include "common/common_types.h"
-
-union Result;
-
-namespace Kernel {
-
-class KPageTable;
-
-/// The possible types of programs that may be indicated
-/// by the program type capability descriptor.
-enum class ProgramType {
- SysModule,
- Application,
- Applet,
-};
-
-/// Handles kernel capability descriptors that are provided by
-/// application metadata. These descriptors provide information
-/// that alters certain parameters for kernel process instance
-/// that will run said application (or applet).
-///
-/// Capabilities are a sequence of flag descriptors, that indicate various
-/// configurations and constraints for a particular process.
-///
-/// Flag types are indicated by a sequence of set low bits. E.g. the
-/// types are indicated with the low bits as follows (where x indicates "don't care"):
-///
-/// - Priority and core mask : 0bxxxxxxxxxxxx0111
-/// - Allowed service call mask: 0bxxxxxxxxxxx01111
-/// - Map physical memory : 0bxxxxxxxxx0111111
-/// - Map IO memory : 0bxxxxxxxx01111111
-/// - Interrupts : 0bxxxx011111111111
-/// - Application type : 0bxx01111111111111
-/// - Kernel version : 0bx011111111111111
-/// - Handle table size : 0b0111111111111111
-/// - Debugger flags : 0b1111111111111111
-///
-/// These are essentially a bit offset subtracted by 1 to create a mask.
-/// e.g. The first entry in the above list is simply bit 3 (value 8 -> 0b1000)
-/// subtracted by one (7 -> 0b0111)
-///
-/// An example of a bit layout (using the map physical layout):
-/// <example>
-/// The MapPhysical type indicates a sequence entry pair of:
-///
-/// [initial, memory_flags], where:
-///
-/// initial:
-/// bits:
-/// 7-24: Starting page to map memory at.
-/// 25 : Indicates if the memory should be mapped as read only.
-///
-/// memory_flags:
-/// bits:
-/// 7-20 : Number of pages to map
-/// 21-25: Seems to be reserved (still checked against though)
-/// 26 : Whether or not the memory being mapped is IO memory, or physical memory
-/// </example>
-///
-class ProcessCapabilities {
-public:
- using InterruptCapabilities = std::bitset<1024>;
- using SyscallCapabilities = std::bitset<192>;
-
- ProcessCapabilities() = default;
- ProcessCapabilities(const ProcessCapabilities&) = delete;
- ProcessCapabilities(ProcessCapabilities&&) = default;
-
- ProcessCapabilities& operator=(const ProcessCapabilities&) = delete;
- ProcessCapabilities& operator=(ProcessCapabilities&&) = default;
-
- /// Initializes this process capabilities instance for a kernel process.
- ///
- /// @param capabilities The capabilities to parse
- /// @param num_capabilities The number of capabilities to parse.
- /// @param page_table The memory manager to use for handling any mapping-related
- /// operations (such as mapping IO memory, etc).
- ///
- /// @returns ResultSuccess if this capabilities instance was able to be initialized,
- /// otherwise, an error code upon failure.
- ///
- Result InitializeForKernelProcess(const u32* capabilities, std::size_t num_capabilities,
- KPageTable& page_table);
-
- /// Initializes this process capabilities instance for a userland process.
- ///
- /// @param capabilities The capabilities to parse.
- /// @param num_capabilities The total number of capabilities to parse.
- /// @param page_table The memory manager to use for handling any mapping-related
- /// operations (such as mapping IO memory, etc).
- ///
- /// @returns ResultSuccess if this capabilities instance was able to be initialized,
- /// otherwise, an error code upon failure.
- ///
- Result InitializeForUserProcess(const u32* capabilities, std::size_t num_capabilities,
- KPageTable& page_table);
-
- /// Initializes this process capabilities instance for a process that does not
- /// have any metadata to parse.
- ///
- /// This is necessary, as we allow running raw executables, and the internal
- /// kernel process capabilities also determine what CPU cores the process is
- /// allowed to run on, and what priorities are allowed for threads. It also
- /// determines the max handle table size, what the program type is, whether or
- /// not the process can be debugged, or whether it's possible for a process to
- /// forcibly debug another process.
- ///
- /// Given the above, this essentially enables all capabilities across the board
- /// for the process. It allows the process to:
- ///
- /// - Run on any core
- /// - Use any thread priority
- /// - Use the maximum amount of handles a process is allowed to.
- /// - Be debuggable
- /// - Forcibly debug other processes.
- ///
- /// Note that this is not a behavior that the kernel allows a process to do via
- /// a single function like this. This is yuzu-specific behavior to handle
- /// executables with no capability descriptors whatsoever to derive behavior from.
- /// It being yuzu-specific is why this is also not the default behavior and not
- /// done by default in the constructor.
- ///
- void InitializeForMetadatalessProcess();
-
- /// Gets the allowable core mask
- u64 GetCoreMask() const {
- return core_mask;
- }
-
- /// Gets the allowable priority mask
- u64 GetPriorityMask() const {
- return priority_mask;
- }
-
- /// Gets the SVC access permission bits
- const SyscallCapabilities& GetServiceCapabilities() const {
- return svc_capabilities;
- }
-
- /// Gets the valid interrupt bits.
- const InterruptCapabilities& GetInterruptCapabilities() const {
- return interrupt_capabilities;
- }
-
- /// Gets the program type for this process.
- ProgramType GetProgramType() const {
- return program_type;
- }
-
- /// Gets the number of total allowable handles for the process' handle table.
- s32 GetHandleTableSize() const {
- return handle_table_size;
- }
-
- /// Gets the kernel version value.
- u32 GetKernelVersion() const {
- return kernel_version;
- }
-
- /// Whether or not this process can be debugged.
- bool IsDebuggable() const {
- return is_debuggable;
- }
-
- /// Whether or not this process can forcibly debug another
- /// process, even if that process is not considered debuggable.
- bool CanForceDebug() const {
- return can_force_debug;
- }
-
-private:
- /// Attempts to parse a given sequence of capability descriptors.
- ///
- /// @param capabilities The sequence of capability descriptors to parse.
- /// @param num_capabilities The number of descriptors within the given sequence.
- /// @param page_table The memory manager that will perform any memory
- /// mapping if necessary.
- ///
- /// @return ResultSuccess if no errors occur, otherwise an error code.
- ///
- Result ParseCapabilities(const u32* capabilities, std::size_t num_capabilities,
- KPageTable& page_table);
-
- /// Attempts to parse a capability descriptor that is only represented by a
- /// single flag set.
- ///
- /// @param set_flags Running set of flags that are used to catch
- /// flags being initialized more than once when they shouldn't be.
- /// @param set_svc_bits Running set of bits representing the allowed supervisor calls mask.
- /// @param flag The flag to attempt to parse.
- /// @param page_table The memory manager that will perform any memory
- /// mapping if necessary.
- ///
- /// @return ResultSuccess if no errors occurred, otherwise an error code.
- ///
- Result ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag,
- KPageTable& page_table);
-
- /// Clears the internal state of this process capability instance. Necessary,
- /// to have a sane starting point due to us allowing running executables without
- /// configuration metadata. We assume a process is not going to have metadata,
- /// and if it turns out that the process does, in fact, have metadata, then
- /// we attempt to parse it. Thus, we need this to reset data members back to
- /// a good state.
- ///
- /// DO NOT ever make this a public member function. This isn't an invariant
- /// anything external should depend upon (and if anything comes to rely on it,
- /// you should immediately be questioning the design of that thing, not this
- /// class. If the kernel itself can run without depending on behavior like that,
- /// then so can yuzu).
- ///
- void Clear();
-
- /// Handles flags related to the priority and core number capability flags.
- Result HandlePriorityCoreNumFlags(u32 flags);
-
- /// Handles flags related to determining the allowable SVC mask.
- Result HandleSyscallFlags(u32& set_svc_bits, u32 flags);
-
- /// Handles flags related to mapping physical memory pages.
- Result HandleMapPhysicalFlags(u32 flags, u32 size_flags, KPageTable& page_table);
-
- /// Handles flags related to mapping IO pages.
- Result HandleMapIOFlags(u32 flags, KPageTable& page_table);
-
- /// Handles flags related to mapping physical memory regions.
- Result HandleMapRegionFlags(u32 flags, KPageTable& page_table);
-
- /// Handles flags related to the interrupt capability flags.
- Result HandleInterruptFlags(u32 flags);
-
- /// Handles flags related to the program type.
- Result HandleProgramTypeFlags(u32 flags);
-
- /// Handles flags related to the handle table size.
- Result HandleHandleTableFlags(u32 flags);
-
- /// Handles flags related to the kernel version capability flags.
- Result HandleKernelVersionFlags(u32 flags);
-
- /// Handles flags related to debug-specific capabilities.
- Result HandleDebugFlags(u32 flags);
-
- SyscallCapabilities svc_capabilities;
- InterruptCapabilities interrupt_capabilities;
-
- u64 core_mask = 0;
- u64 priority_mask = 0;
-
- s32 handle_table_size = 0;
- u32 kernel_version = 0;
-
- ProgramType program_type = ProgramType::SysModule;
-
- bool is_debuggable = false;
- bool can_force_debug = false;
-};
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp
index 97f1210de..4ca62860d 100644
--- a/src/core/hle/kernel/svc/svc_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_memory.cpp
@@ -29,7 +29,8 @@ constexpr bool IsValidAddressRange(u64 address, u64 size) {
// Helper function that performs the common sanity checks for svcMapMemory
// and svcUnmapMemory. This is doable, as both functions perform their sanitizing
// in the same order.
-Result MapUnmapMemorySanityChecks(const KPageTable& manager, u64 dst_addr, u64 src_addr, u64 size) {
+Result MapUnmapMemorySanityChecks(const KProcessPageTable& manager, u64 dst_addr, u64 src_addr,
+ u64 size) {
if (!Common::Is4KBAligned(dst_addr)) {
LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr);
R_THROW(ResultInvalidAddress);
@@ -123,7 +124,8 @@ Result SetMemoryAttribute(Core::System& system, u64 address, u64 size, u32 mask,
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Set the memory attribute.
- R_RETURN(page_table.SetMemoryAttribute(address, size, mask, attr));
+ R_RETURN(page_table.SetMemoryAttribute(address, size, static_cast<KMemoryAttribute>(mask),
+ static_cast<KMemoryAttribute>(attr)));
}
/// Maps a memory range into a different range.
diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp
index 99330d02a..793e9f8d0 100644
--- a/src/core/hle/kernel/svc/svc_physical_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp
@@ -16,7 +16,14 @@ Result SetHeapSize(Core::System& system, u64* out_address, u64 size) {
R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize);
// Set the heap size.
- R_RETURN(GetCurrentProcess(system.Kernel()).GetPageTable().SetHeapSize(out_address, size));
+ KProcessAddress address{};
+ R_TRY(GetCurrentProcess(system.Kernel())
+ .GetPageTable()
+ .SetHeapSize(std::addressof(address), size));
+
+ // We succeeded.
+ *out_address = GetInteger(address);
+ R_SUCCEED();
}
/// Maps memory at a desired address
diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp
index 07cd48175..e1427947b 100644
--- a/src/core/hle/kernel/svc/svc_process_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_process_memory.cpp
@@ -247,8 +247,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
R_THROW(ResultInvalidCurrentMemory);
}
- R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size,
- KPageTable::ICacheInvalidationStrategy::InvalidateAll));
+ R_RETURN(page_table.UnmapCodeMemory(dst_address, src_address, size));
}
Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address,
diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp
index 51af06e97..816dcb8d0 100644
--- a/src/core/hle/kernel/svc/svc_query_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_query_memory.cpp
@@ -31,12 +31,12 @@ Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageIn
}
auto& current_memory{GetCurrentMemory(system.Kernel())};
- const auto memory_info{process->GetPageTable().QueryInfo(address).GetSvcMemoryInfo()};
- current_memory.WriteBlock(out_memory_info, std::addressof(memory_info), sizeof(memory_info));
+ KMemoryInfo mem_info;
+ R_TRY(process->GetPageTable().QueryInfo(std::addressof(mem_info), out_page_info, address));
- //! This is supposed to be part of the QueryInfo call.
- *out_page_info = {};
+ const auto svc_mem_info = mem_info.GetSvcMemoryInfo();
+ current_memory.WriteBlock(out_memory_info, std::addressof(svc_mem_info), sizeof(svc_mem_info));
R_SUCCEED();
}
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index dd0b27f47..749f51f69 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -407,3 +407,34 @@ constexpr inline Result __TmpCurrentResultReference = ResultSuccess;
/// Evaluates a boolean expression, and succeeds if that expression is true.
#define R_SUCCEED_IF(expr) R_UNLESS(!(expr), ResultSuccess)
+
+#define R_TRY_CATCH(res_expr) \
+ { \
+ const auto R_CURRENT_RESULT = (res_expr); \
+ if (R_FAILED(R_CURRENT_RESULT)) { \
+ if (false)
+
+#define R_END_TRY_CATCH \
+ else if (R_FAILED(R_CURRENT_RESULT)) { \
+ R_THROW(R_CURRENT_RESULT); \
+ } \
+ } \
+ }
+
+#define R_CATCH_ALL() \
+ } \
+ else if (R_FAILED(R_CURRENT_RESULT)) { \
+ if (true)
+
+#define R_CATCH(res_expr) \
+ } \
+ else if ((res_expr) == (R_CURRENT_RESULT)) { \
+ if (true)
+
+#define R_CONVERT(catch_type, convert_type) \
+ R_CATCH(catch_type) { R_THROW(static_cast<Result>(convert_type)); }
+
+#define R_CONVERT_ALL(convert_type) \
+ R_CATCH_ALL() { R_THROW(static_cast<Result>(convert_type)); }
+
+#define R_ASSERT(res_expr) ASSERT(R_SUCCEEDED(res_expr))
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 1b1c8190e..f21553644 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -3,11 +3,13 @@
#include <algorithm>
#include <array>
+
#include "common/common_types.h"
#include "common/fs/file.h"
#include "common/fs/path_util.h"
#include "common/logging/log.h"
#include "common/polyfill_ranges.h"
+#include "common/stb.h"
#include "common/string_util.h"
#include "common/swap.h"
#include "core/constants.h"
@@ -38,9 +40,36 @@ static std::filesystem::path GetImagePath(const Common::UUID& uuid) {
fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString());
}
-static constexpr u32 SanitizeJPEGSize(std::size_t size) {
+static void JPGToMemory(void* context, void* data, int len) {
+ std::vector<u8>* jpg_image = static_cast<std::vector<u8>*>(context);
+ unsigned char* jpg = static_cast<unsigned char*>(data);
+ jpg_image->insert(jpg_image->end(), jpg, jpg + len);
+}
+
+static void SanitizeJPEGImageSize(std::vector<u8>& image) {
constexpr std::size_t max_jpeg_image_size = 0x20000;
- return static_cast<u32>(std::min(size, max_jpeg_image_size));
+ constexpr int profile_dimensions = 256;
+ int original_width, original_height, color_channels;
+
+ const auto plain_image =
+ stbi_load_from_memory(image.data(), static_cast<int>(image.size()), &original_width,
+ &original_height, &color_channels, STBI_rgb);
+
+ // Resize image to match 256*256
+ if (original_width != profile_dimensions || original_height != profile_dimensions) {
+ // Use vector instead of array to avoid overflowing the stack
+ std::vector<u8> out_image(profile_dimensions * profile_dimensions * STBI_rgb);
+ stbir_resize_uint8_srgb(plain_image, original_width, original_height, 0, out_image.data(),
+ profile_dimensions, profile_dimensions, 0, STBI_rgb, 0,
+ STBIR_FILTER_BOX);
+ image.clear();
+ if (!stbi_write_jpg_to_func(JPGToMemory, &image, profile_dimensions, profile_dimensions,
+ STBI_rgb, out_image.data(), 0)) {
+ LOG_ERROR(Service_ACC, "Failed to resize the user provided image.");
+ }
+ }
+
+ image.resize(std::min(image.size(), max_jpeg_image_size));
}
class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> {
@@ -339,19 +368,20 @@ protected:
LOG_WARNING(Service_ACC,
"Failed to load user provided image! Falling back to built-in backup...");
ctx.WriteBuffer(Core::Constants::ACCOUNT_BACKUP_JPEG);
- rb.Push(SanitizeJPEGSize(Core::Constants::ACCOUNT_BACKUP_JPEG.size()));
+ rb.Push(static_cast<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size()));
return;
}
- const u32 size = SanitizeJPEGSize(image.GetSize());
- std::vector<u8> buffer(size);
+ std::vector<u8> buffer(image.GetSize());
if (image.Read(buffer) != buffer.size()) {
LOG_ERROR(Service_ACC, "Failed to read all the bytes in the user provided image.");
}
+ SanitizeJPEGImageSize(buffer);
+
ctx.WriteBuffer(buffer);
- rb.Push<u32>(size);
+ rb.Push(static_cast<u32>(buffer.size()));
}
void GetImageSize(HLERequestContext& ctx) {
@@ -365,10 +395,18 @@ protected:
if (!image.IsOpen()) {
LOG_WARNING(Service_ACC,
"Failed to load user provided image! Falling back to built-in backup...");
- rb.Push(SanitizeJPEGSize(Core::Constants::ACCOUNT_BACKUP_JPEG.size()));
- } else {
- rb.Push(SanitizeJPEGSize(image.GetSize()));
+ rb.Push(static_cast<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size()));
+ return;
}
+
+ std::vector<u8> buffer(image.GetSize());
+
+ if (image.Read(buffer) != buffer.size()) {
+ LOG_ERROR(Service_ACC, "Failed to read all the bytes in the user provided image.");
+ }
+
+ SanitizeJPEGImageSize(buffer);
+ rb.Push(static_cast<u32>(buffer.size()));
}
void Store(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index cc643ea09..a266d7c21 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -13,6 +13,7 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/savedata_factory.h"
+#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h"
@@ -21,6 +22,7 @@
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/am/applets/applet_cabinet.h"
+#include "core/hle/service/am/applets/applet_controller.h"
#include "core/hle/service/am/applets/applet_mii_edit_types.h"
#include "core/hle/service/am/applets/applet_profile_select.h"
#include "core/hle/service/am/applets/applet_software_keyboard_types.h"
@@ -35,6 +37,7 @@
#include "core/hle/service/caps/caps_su.h"
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/filesystem/filesystem.h"
+#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
@@ -73,7 +76,7 @@ IWindowController::IWindowController(Core::System& system_)
static const FunctionInfo functions[] = {
{0, nullptr, "CreateWindow"},
{1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
- {2, nullptr, "GetAppletResourceUserIdOfCallerApplet"},
+ {2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"},
{10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
{11, nullptr, "ReleaseForegroundRights"},
{12, nullptr, "RejectToChangeIntoBackground"},
@@ -97,6 +100,16 @@ void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) {
rb.Push<u64>(process_id);
}
+void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) {
+ const u64 process_id = 0;
+
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u64>(process_id);
+}
+
void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
@@ -1565,7 +1578,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
{6, nullptr, "GetPopInteractiveInDataEvent"},
{10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
{11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
- {12, nullptr, "GetMainAppletIdentityInfo"},
+ {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"},
{13, nullptr, "CanUseApplicationCore"},
{14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
{15, nullptr, "GetMainAppletApplicationControlProperty"},
@@ -1609,6 +1622,9 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
case Applets::AppletId::SoftwareKeyboard:
PushInShowSoftwareKeyboard();
break;
+ case Applets::AppletId::Controller:
+ PushInShowController();
+ break;
default:
break;
}
@@ -1666,13 +1682,33 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
rb.PushRaw(applet_info);
}
-void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
+void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) {
struct AppletIdentityInfo {
Applets::AppletId applet_id;
INSERT_PADDING_BYTES(0x4);
u64 application_id;
};
+ static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
+
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ const AppletIdentityInfo applet_info{
+ .applet_id = Applets::AppletId::QLaunch,
+ .application_id = 0x0100000000001000ull,
+ };
+
+ IPC::ResponseBuilder rb{ctx, 6};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(applet_info);
+}
+void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
+ struct AppletIdentityInfo {
+ Applets::AppletId applet_id;
+ INSERT_PADDING_BYTES(0x4);
+ u64 application_id;
+ };
+ static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
LOG_WARNING(Service_AM, "(STUBBED) called");
const AppletIdentityInfo applet_info{
@@ -1737,6 +1773,55 @@ void ILibraryAppletSelfAccessor::PushInShowAlbum() {
queue_data.emplace_back(std::move(settings_data));
}
+void ILibraryAppletSelfAccessor::PushInShowController() {
+ const Applets::CommonArguments common_args = {
+ .arguments_version = Applets::CommonArgumentVersion::Version3,
+ .size = Applets::CommonArgumentSize::Version3,
+ .library_version = static_cast<u32>(Applets::ControllerAppletVersion::Version8),
+ .theme_color = Applets::ThemeColor::BasicBlack,
+ .play_startup_sound = true,
+ .system_tick = system.CoreTiming().GetClockTicks(),
+ };
+
+ Applets::ControllerSupportArgNew user_args = {
+ .header = {.player_count_min = 1,
+ .player_count_max = 4,
+ .enable_take_over_connection = true,
+ .enable_left_justify = false,
+ .enable_permit_joy_dual = true,
+ .enable_single_mode = false,
+ .enable_identification_color = false},
+ .identification_colors = {},
+ .enable_explain_text = false,
+ .explain_text = {},
+ };
+
+ Applets::ControllerSupportArgPrivate private_args = {
+ .arg_private_size = sizeof(Applets::ControllerSupportArgPrivate),
+ .arg_size = sizeof(Applets::ControllerSupportArgNew),
+ .is_home_menu = true,
+ .flag_1 = true,
+ .mode = Applets::ControllerSupportMode::ShowControllerSupport,
+ .caller = Applets::ControllerSupportCaller::
+ Application, // switchbrew: Always zero except with
+ // ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem,
+ // which sets this to the input param
+ .style_set = Core::HID::NpadStyleSet::None,
+ .joy_hold_type = 0,
+ };
+ std::vector<u8> common_args_data(sizeof(common_args));
+ std::vector<u8> private_args_data(sizeof(private_args));
+ std::vector<u8> user_args_data(sizeof(user_args));
+
+ std::memcpy(common_args_data.data(), &common_args, sizeof(common_args));
+ std::memcpy(private_args_data.data(), &private_args, sizeof(private_args));
+ std::memcpy(user_args_data.data(), &user_args, sizeof(user_args));
+
+ queue_data.emplace_back(std::move(common_args_data));
+ queue_data.emplace_back(std::move(private_args_data));
+ queue_data.emplace_back(std::move(user_args_data));
+}
+
void ILibraryAppletSelfAccessor::PushInShowCabinetData() {
const Applets::CommonArguments arguments{
.arguments_version = Applets::CommonArgumentVersion::Version3,
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 8f8cb8a9e..905a71b9f 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -87,6 +87,7 @@ public:
private:
void GetAppletResourceUserId(HLERequestContext& ctx);
+ void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx);
void AcquireForegroundRights(HLERequestContext& ctx);
};
@@ -345,6 +346,7 @@ private:
void PopInData(HLERequestContext& ctx);
void PushOutData(HLERequestContext& ctx);
void GetLibraryAppletInfo(HLERequestContext& ctx);
+ void GetMainAppletIdentityInfo(HLERequestContext& ctx);
void ExitProcessAndReturn(HLERequestContext& ctx);
void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
void GetDesirableKeyboardLayout(HLERequestContext& ctx);
@@ -355,6 +357,7 @@ private:
void PushInShowCabinetData();
void PushInShowMiiEditData();
void PushInShowSoftwareKeyboard();
+ void PushInShowController();
std::deque<std::vector<u8>> queue_data;
};
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp
index b379dadeb..9d1960cb7 100644
--- a/src/core/hle/service/am/applets/applet_cabinet.cpp
+++ b/src/core/hle/service/am/applets/applet_cabinet.cpp
@@ -122,7 +122,8 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name)
Service::NFP::RegisterInfoPrivate register_info{};
std::memcpy(register_info.amiibo_name.data(), amiibo_name.data(),
std::min(amiibo_name.size(), register_info.amiibo_name.size() - 1));
-
+ register_info.mii_store_data.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All);
+ register_info.mii_store_data.SetNickname({u'y', u'u', u'z', u'u'});
nfp_device->SetRegisterInfoPrivate(register_info);
break;
}
diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h
index f6c64f633..9f839f3d7 100644
--- a/src/core/hle/service/am/applets/applet_controller.h
+++ b/src/core/hle/service/am/applets/applet_controller.h
@@ -56,7 +56,7 @@ enum class ControllerSupportResult : u32 {
struct ControllerSupportArgPrivate {
u32 arg_private_size{};
u32 arg_size{};
- bool flag_0{};
+ bool is_home_menu{};
bool flag_1{};
ControllerSupportMode mode{};
ControllerSupportCaller caller{};
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp
index 1c9a1dc29..b0ea2b381 100644
--- a/src/core/hle/service/am/applets/applet_web_browser.cpp
+++ b/src/core/hle/service/am/applets/applet_web_browser.cpp
@@ -330,8 +330,7 @@ void WebBrowser::ExtractOfflineRomFS() {
LOG_DEBUG(Service_AM, "Extracting RomFS to {}",
Common::FS::PathToUTF8String(offline_cache_dir));
- const auto extracted_romfs_dir =
- FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard);
+ const auto extracted_romfs_dir = FileSys::ExtractRomFS(offline_romfs);
const auto temp_dir = system.GetFilesystem()->CreateDirectory(
Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite);
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index f02bbc450..0bf2598b7 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -69,6 +69,30 @@ enum class AppletId : u32 {
MyPage = 0x1A,
};
+enum class AppletProgramId : u64 {
+ QLaunch = 0x0100000000001000ull,
+ Auth = 0x0100000000001001ull,
+ Cabinet = 0x0100000000001002ull,
+ Controller = 0x0100000000001003ull,
+ DataErase = 0x0100000000001004ull,
+ Error = 0x0100000000001005ull,
+ NetConnect = 0x0100000000001006ull,
+ ProfileSelect = 0x0100000000001007ull,
+ SoftwareKeyboard = 0x0100000000001008ull,
+ MiiEdit = 0x0100000000001009ull,
+ Web = 0x010000000000100Aull,
+ Shop = 0x010000000000100Bull,
+ OverlayDisplay = 0x010000000000100Cull,
+ PhotoViewer = 0x010000000000100Dull,
+ Settings = 0x010000000000100Eull,
+ OfflineWeb = 0x010000000000100Full,
+ LoginShare = 0x0100000000001010ull,
+ WebAuth = 0x0100000000001011ull,
+ Starter = 0x0100000000001012ull,
+ MyPage = 0x0100000000001013ull,
+ MaxProgramId = 0x0100000000001FFFull,
+};
+
enum class LibraryAppletMode : u32 {
AllForeground = 0,
Background = 1,
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 8069f75b7..c65e32489 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -127,7 +127,7 @@ public:
private:
void GetCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_BTM, "called");
+ LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
@@ -263,13 +263,13 @@ public:
explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "StartGamepadPairing"},
- {1, nullptr, "CancelGamepadPairing"},
+ {0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"},
+ {1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"},
{2, nullptr, "ClearGamepadPairingDatabase"},
{3, nullptr, "GetPairedGamepadCount"},
{4, nullptr, "EnableRadio"},
{5, nullptr, "DisableRadio"},
- {6, nullptr, "GetRadioOnOff"},
+ {6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"},
{7, nullptr, "AcquireRadioEvent"},
{8, nullptr, "AcquireGamepadPairingEvent"},
{9, nullptr, "IsGamepadPairingStarted"},
@@ -280,18 +280,58 @@ public:
{14, nullptr, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
- {17, nullptr, "GetConnectedAudioDevices"},
+ {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"},
{18, nullptr, "DisconnectAudioDevice"},
{19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
{20, nullptr, "GetPairedAudioDevices"},
{21, nullptr, "RemoveAudioDevicePairing"},
- {22, nullptr, "RequestAudioDeviceConnectionRejection"},
- {23, nullptr, "CancelAudioDeviceConnectionRejection"}
+ {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"},
+ {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"}
};
// clang-format on
RegisterHandlers(functions);
}
+
+private:
+ void IsRadioEnabled(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(true);
+ }
+
+ void StartGamepadPairing(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void CancelGamepadPairing(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void GetConnectedAudioDevices(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push<u32>(0);
+ }
+
+ void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
};
class BTM_SYS final : public ServiceFramework<BTM_SYS> {
@@ -308,7 +348,7 @@ public:
private:
void GetCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_BTM, "called");
+ LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index 9d05f9801..0507b14e7 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -32,7 +32,7 @@ public:
{10200, nullptr, "SendFriendRequestForApplication"},
{10211, nullptr, "AddFacedFriendRequestForApplication"},
{10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"},
- {10420, nullptr, "IsBlockedUserListCacheAvailable"},
+ {10420, &IFriendService::CheckBlockedUserListAvailability, "CheckBlockedUserListAvailability"},
{10421, nullptr, "EnsureBlockedUserListAvailable"},
{10500, nullptr, "GetProfileList"},
{10600, nullptr, "DeclareOpenOnlinePlaySession"},
@@ -206,6 +206,17 @@ private:
rb.Push(true);
}
+ void CheckBlockedUserListAvailability(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto uuid{rp.PopRaw<Common::UUID>()};
+
+ LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString());
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(true);
+ }
+
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* completion_event;
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp
new file mode 100644
index 000000000..b2bf1d78d
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/console_six_axis.cpp
@@ -0,0 +1,42 @@
+// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core.h"
+#include "core/core_timing.h"
+#include "core/hid/emulated_console.h"
+#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/controllers/console_six_axis.h"
+#include "core/memory.h"
+
+namespace Service::HID {
+constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
+
+ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
+ : ControllerBase{hid_core_} {
+ console = hid_core.GetEmulatedConsole();
+ static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
+ "ConsoleSharedMemory is bigger than the shared memory");
+ shared_memory = std::construct_at(
+ reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
+}
+
+ConsoleSixAxis::~ConsoleSixAxis() = default;
+
+void ConsoleSixAxis::OnInit() {}
+
+void ConsoleSixAxis::OnRelease() {}
+
+void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!IsControllerActivated()) {
+ return;
+ }
+
+ const auto motion_status = console->GetMotion();
+
+ shared_memory->sampling_number++;
+ shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
+ shared_memory->verticalization_error = motion_status.verticalization_error;
+ shared_memory->gyro_bias = motion_status.gyro_bias;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h
new file mode 100644
index 000000000..5b7c6a29a
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/console_six_axis.h
@@ -0,0 +1,43 @@
+// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/vector_math.h"
+#include "core/hle/service/hid/controllers/controller_base.h"
+
+namespace Core::HID {
+class EmulatedConsole;
+} // namespace Core::HID
+
+namespace Service::HID {
+class ConsoleSixAxis final : public ControllerBase {
+public:
+ explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
+ ~ConsoleSixAxis() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+private:
+ // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
+ struct ConsoleSharedMemory {
+ u64 sampling_number{};
+ bool is_seven_six_axis_sensor_at_rest{};
+ INSERT_PADDING_BYTES(3); // padding
+ f32 verticalization_error{};
+ Common::Vec3f gyro_bias{};
+ INSERT_PADDING_BYTES(4); // padding
+ };
+ static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
+
+ ConsoleSharedMemory* shared_memory = nullptr;
+ Core::HID::EmulatedConsole* console = nullptr;
+};
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp
index c58d67d7d..0bcd87062 100644
--- a/src/core/hle/service/hid/controllers/controller_base.cpp
+++ b/src/core/hle/service/hid/controllers/controller_base.cpp
@@ -8,12 +8,17 @@ namespace Service::HID {
ControllerBase::ControllerBase(Core::HID::HIDCore& hid_core_) : hid_core(hid_core_) {}
ControllerBase::~ControllerBase() = default;
-void ControllerBase::ActivateController() {
+Result ControllerBase::Activate() {
if (is_activated) {
- return;
+ return ResultSuccess;
}
is_activated = true;
OnInit();
+ return ResultSuccess;
+}
+
+Result ControllerBase::Activate(u64 aruid) {
+ return Activate();
}
void ControllerBase::DeactivateController() {
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
index d6f7a5073..9a44ee41e 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -4,6 +4,7 @@
#pragma once
#include "common/common_types.h"
+#include "core/hle/result.h"
namespace Core::Timing {
class CoreTiming;
@@ -31,7 +32,8 @@ public:
// When the controller is requesting a motion update for the shared memory
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {}
- void ActivateController();
+ Result Activate();
+ Result Activate(u64 aruid);
void DeactivateController();
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index 8ec9f4a95..9de19ebfc 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -13,7 +13,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000;
-Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
+DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size,
"DebugPadSharedMemory is bigger than the shared memory");
@@ -22,13 +22,13 @@ Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
}
-Controller_DebugPad::~Controller_DebugPad() = default;
+DebugPad::~DebugPad() = default;
-void Controller_DebugPad::OnInit() {}
+void DebugPad::OnInit() {}
-void Controller_DebugPad::OnRelease() {}
+void DebugPad::OnRelease() {}
-void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->debug_pad_lifo.buffer_count = 0;
shared_memory->debug_pad_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
index 68ff0ea79..5566dba77 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -15,10 +15,10 @@ struct AnalogStickState;
} // namespace Core::HID
namespace Service::HID {
-class Controller_DebugPad final : public ControllerBase {
+class DebugPad final : public ControllerBase {
public:
- explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
- ~Controller_DebugPad() override;
+ explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
+ ~DebugPad() override;
// Called when the controller is initialized
void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index 63eecd42b..59b2ec73c 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -23,7 +23,7 @@ constexpr f32 Square(s32 num) {
return static_cast<f32>(num * num);
}
-Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
+Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase(hid_core_) {
static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size,
"GestureSharedMemory is bigger than the shared memory");
@@ -31,17 +31,17 @@ Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_sh
reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
console = hid_core.GetEmulatedConsole();
}
-Controller_Gesture::~Controller_Gesture() = default;
+Gesture::~Gesture() = default;
-void Controller_Gesture::OnInit() {
+void Gesture::OnInit() {
shared_memory->gesture_lifo.buffer_count = 0;
shared_memory->gesture_lifo.buffer_tail = 0;
force_update = true;
}
-void Controller_Gesture::OnRelease() {}
+void Gesture::OnRelease() {}
-void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->gesture_lifo.buffer_count = 0;
shared_memory->gesture_lifo.buffer_tail = 0;
@@ -64,7 +64,7 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
UpdateGestureSharedMemory(gesture, time_difference);
}
-void Controller_Gesture::ReadTouchInput() {
+void Gesture::ReadTouchInput() {
if (!Settings::values.touchscreen.enabled) {
fingers = {};
return;
@@ -76,8 +76,7 @@ void Controller_Gesture::ReadTouchInput() {
}
}
-bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
- f32 time_difference) {
+bool Gesture::ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
if (force_update) {
force_update = false;
@@ -100,8 +99,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
return false;
}
-void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture,
- f32 time_difference) {
+void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) {
GestureType type = GestureType::Idle;
GestureAttribute attributes{};
@@ -138,8 +136,8 @@ void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture,
shared_memory->gesture_lifo.WriteNextEntry(next_state);
}
-void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
- GestureAttribute& attributes) {
+void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
+ GestureAttribute& attributes) {
const auto& last_entry = GetLastGestureEntry();
gesture.detection_count++;
@@ -152,8 +150,8 @@ void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& typ
}
}
-void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type,
- f32 time_difference) {
+void Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type,
+ f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
// Promote to pan type if touch moved
@@ -186,9 +184,8 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Gestu
}
}
-void Controller_Gesture::EndGesture(GestureProperties& gesture,
- GestureProperties& last_gesture_props, GestureType& type,
- GestureAttribute& attributes, f32 time_difference) {
+void Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props,
+ GestureType& type, GestureAttribute& attributes, f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
if (last_gesture_props.active_points != 0) {
@@ -222,9 +219,8 @@ void Controller_Gesture::EndGesture(GestureProperties& gesture,
}
}
-void Controller_Gesture::SetTapEvent(GestureProperties& gesture,
- GestureProperties& last_gesture_props, GestureType& type,
- GestureAttribute& attributes) {
+void Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
+ GestureType& type, GestureAttribute& attributes) {
type = GestureType::Tap;
gesture = last_gesture_props;
force_update = true;
@@ -236,9 +232,8 @@ void Controller_Gesture::SetTapEvent(GestureProperties& gesture,
}
}
-void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
- GestureProperties& last_gesture_props, GestureType& type,
- f32 time_difference) {
+void Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
+ GestureType& type, f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
next_state.delta = gesture.mid_point - last_entry.pos;
@@ -263,9 +258,8 @@ void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
}
}
-void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
- GestureProperties& last_gesture_props, GestureType& type,
- f32 time_difference) {
+void Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
+ GestureType& type, f32 time_difference) {
const auto& last_entry = GetLastGestureEntry();
next_state.vel_x =
static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference);
@@ -287,8 +281,8 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
force_update = true;
}
-void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
- GestureProperties& last_gesture_props, GestureType& type) {
+void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
+ GestureType& type) {
const auto& last_entry = GetLastGestureEntry();
type = GestureType::Swipe;
@@ -311,11 +305,11 @@ void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
next_state.direction = GestureDirection::Up;
}
-const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const {
+const Gesture::GestureState& Gesture::GetLastGestureEntry() const {
return shared_memory->gesture_lifo.ReadCurrentEntry().state;
}
-Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() {
+Gesture::GestureProperties Gesture::GetGestureProperties() {
GestureProperties gesture;
std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers;
const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(),
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 0d6099ea0..4c6f8ee07 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -12,10 +12,10 @@
#include "core/hle/service/hid/ring_lifo.h"
namespace Service::HID {
-class Controller_Gesture final : public ControllerBase {
+class Gesture final : public ControllerBase {
public:
- explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
- ~Controller_Gesture() override;
+ explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
+ ~Gesture() override;
// Called when the controller is initialized
void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 117d87433..ddb1b0ba4 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -12,7 +12,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
-Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
+Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size,
"KeyboardSharedMemory is bigger than the shared memory");
@@ -21,13 +21,13 @@ Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_
emulated_devices = hid_core.GetEmulatedDevices();
}
-Controller_Keyboard::~Controller_Keyboard() = default;
+Keyboard::~Keyboard() = default;
-void Controller_Keyboard::OnInit() {}
+void Keyboard::OnInit() {}
-void Controller_Keyboard::OnRelease() {}
+void Keyboard::OnRelease() {}
-void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->keyboard_lifo.buffer_count = 0;
shared_memory->keyboard_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index 7532f53c6..172ec1309 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -14,10 +14,10 @@ struct KeyboardKey;
} // namespace Core::HID
namespace Service::HID {
-class Controller_Keyboard final : public ControllerBase {
+class Keyboard final : public ControllerBase {
public:
- explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
- ~Controller_Keyboard() override;
+ explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
+ ~Keyboard() override;
// Called when the controller is initialized
void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index 0afc66681..6e5a04e34 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -12,8 +12,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
-Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
- : ControllerBase{hid_core_} {
+Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size,
"MouseSharedMemory is bigger than the shared memory");
shared_memory = std::construct_at(
@@ -21,12 +20,12 @@ Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared
emulated_devices = hid_core.GetEmulatedDevices();
}
-Controller_Mouse::~Controller_Mouse() = default;
+Mouse::~Mouse() = default;
-void Controller_Mouse::OnInit() {}
-void Controller_Mouse::OnRelease() {}
+void Mouse::OnInit() {}
+void Mouse::OnRelease() {}
-void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->mouse_lifo.buffer_count = 0;
shared_memory->mouse_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 733d00577..a80f3823f 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -14,10 +14,10 @@ struct AnalogStickState;
} // namespace Core::HID
namespace Service::HID {
-class Controller_Mouse final : public ControllerBase {
+class Mouse final : public ControllerBase {
public:
- explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
- ~Controller_Mouse() override;
+ explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
+ ~Mouse() override;
// Called when the controller is initialized
void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index bc822f19e..08ee9de9c 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -18,6 +18,7 @@
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/errors.h"
+#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/kernel_helpers.h"
namespace Service::HID {
@@ -29,60 +30,8 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
Core::HID::NpadIdType::Handheld,
};
-bool Controller_NPad::IsNpadIdValid(Core::HID::NpadIdType npad_id) {
- switch (npad_id) {
- case Core::HID::NpadIdType::Player1:
- case Core::HID::NpadIdType::Player2:
- case Core::HID::NpadIdType::Player3:
- case Core::HID::NpadIdType::Player4:
- case Core::HID::NpadIdType::Player5:
- case Core::HID::NpadIdType::Player6:
- case Core::HID::NpadIdType::Player7:
- case Core::HID::NpadIdType::Player8:
- case Core::HID::NpadIdType::Other:
- case Core::HID::NpadIdType::Handheld:
- return true;
- default:
- LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
- return false;
- }
-}
-
-Result Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) {
- const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
- const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
- const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
-
- if (!npad_type) {
- return VibrationInvalidStyleIndex;
- }
- if (!npad_id) {
- return VibrationInvalidNpadId;
- }
- if (!device_index) {
- return VibrationDeviceIndexOutOfRange;
- }
-
- return ResultSuccess;
-}
-
-Result Controller_NPad::VerifyValidSixAxisSensorHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) {
- const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
- const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
-
- if (!npad_id) {
- return InvalidNpadId;
- }
- if (!device_index) {
- return NpadDeviceIndexOutOfRange;
- }
-
- return ResultSuccess;
-}
-
-Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
- KernelHelpers::ServiceContext& service_context_)
+NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
+ KernelHelpers::ServiceContext& service_context_)
: ControllerBase{hid_core_}, service_context{service_context_} {
static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size);
for (std::size_t i = 0; i < controller_data.size(); ++i) {
@@ -103,7 +52,7 @@ Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_m
}
}
-Controller_NPad::~Controller_NPad() {
+NPad::~NPad() {
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
controller.device->DeleteCallback(controller.callback_key);
@@ -111,8 +60,7 @@ Controller_NPad::~Controller_NPad() {
OnRelease();
}
-void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
- std::size_t controller_idx) {
+void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) {
if (type == Core::HID::ControllerTriggerType::All) {
ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
@@ -150,7 +98,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
}
}
-void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
+void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) {
return;
@@ -344,12 +292,13 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
Common::Input::PollingMode::Active);
}
+
SignalStyleSetChangedEvent(npad_id);
WriteEmptyEntry(controller.shared_memory);
hid_core.SetLastActiveController(npad_id);
}
-void Controller_NPad::OnInit() {
+void NPad::OnInit() {
if (!IsControllerActivated()) {
return;
}
@@ -383,7 +332,7 @@ void Controller_NPad::OnInit() {
}
}
-void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) {
+void NPad::WriteEmptyEntry(NpadInternalState* npad) {
NPadGenericState dummy_pad_state{};
NpadGcTriggerState dummy_gc_state{};
dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
@@ -404,7 +353,7 @@ void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) {
npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
}
-void Controller_NPad::OnRelease() {
+void NPad::OnRelease() {
is_controller_initialized = false;
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
@@ -415,7 +364,7 @@ void Controller_NPad::OnRelease() {
}
}
-void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
+void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
std::scoped_lock lock{mutex};
auto& controller = GetControllerFromNpadIdType(npad_id);
const auto controller_type = controller.device->GetNpadStyleIndex();
@@ -457,12 +406,14 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
pad_entry.l_stick = stick_state.left;
}
- if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft) {
+ if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft ||
+ controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl);
pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr);
}
- if (controller_type == Core::HID::NpadStyleIndex::JoyconRight) {
+ if (controller_type == Core::HID::NpadStyleIndex::JoyconRight ||
+ controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl);
pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr);
}
@@ -482,7 +433,7 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
}
}
-void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
@@ -612,134 +563,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
}
}
-void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!IsControllerActivated()) {
- return;
- }
-
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- auto& controller = controller_data[i];
-
- const auto& controller_type = controller.device->GetNpadStyleIndex();
-
- if (controller_type == Core::HID::NpadStyleIndex::None ||
- !controller.device->IsConnected()) {
- continue;
- }
-
- auto* npad = controller.shared_memory;
- const auto& motion_state = controller.device->GetMotions();
- auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
- auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
- auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
- auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
- auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
- auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
-
- // Clear previous state
- sixaxis_fullkey_state = {};
- sixaxis_handheld_state = {};
- sixaxis_dual_left_state = {};
- sixaxis_dual_right_state = {};
- sixaxis_left_lifo_state = {};
- sixaxis_right_lifo_state = {};
-
- if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
- controller.sixaxis_at_rest = true;
- for (std::size_t e = 0; e < motion_state.size(); ++e) {
- controller.sixaxis_at_rest =
- controller.sixaxis_at_rest && motion_state[e].is_at_rest;
- }
- }
-
- const auto set_motion_state = [&](SixAxisSensorState& state,
- const Core::HID::ControllerMotion& hid_state) {
- using namespace std::literals::chrono_literals;
- static constexpr SixAxisSensorState default_motion_state = {
- .delta_time = std::chrono::nanoseconds(5ms).count(),
- .accel = {0, 0, -1.0f},
- .orientation =
- {
- Common::Vec3f{1.0f, 0, 0},
- Common::Vec3f{0, 1.0f, 0},
- Common::Vec3f{0, 0, 1.0f},
- },
- .attribute = {1},
- };
- if (!controller.sixaxis_sensor_enabled) {
- state = default_motion_state;
- return;
- }
- if (!Settings::values.motion_enabled.GetValue()) {
- state = default_motion_state;
- return;
- }
- state.attribute.is_connected.Assign(1);
- state.delta_time = std::chrono::nanoseconds(5ms).count();
- state.accel = hid_state.accel;
- state.gyro = hid_state.gyro;
- state.rotation = hid_state.rotation;
- state.orientation = hid_state.orientation;
- };
-
- switch (controller_type) {
- case Core::HID::NpadStyleIndex::None:
- ASSERT(false);
- break;
- case Core::HID::NpadStyleIndex::ProController:
- set_motion_state(sixaxis_fullkey_state, motion_state[0]);
- break;
- case Core::HID::NpadStyleIndex::Handheld:
- set_motion_state(sixaxis_handheld_state, motion_state[0]);
- break;
- case Core::HID::NpadStyleIndex::JoyconDual:
- set_motion_state(sixaxis_dual_left_state, motion_state[0]);
- set_motion_state(sixaxis_dual_right_state, motion_state[1]);
- break;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
- break;
- case Core::HID::NpadStyleIndex::JoyconRight:
- set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
- break;
- case Core::HID::NpadStyleIndex::Pokeball:
- using namespace std::literals::chrono_literals;
- set_motion_state(sixaxis_fullkey_state, motion_state[0]);
- sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
- break;
- default:
- break;
- }
-
- sixaxis_fullkey_state.sampling_number =
- npad->sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_handheld_state.sampling_number =
- npad->sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_dual_left_state.sampling_number =
- npad->sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_dual_right_state.sampling_number =
- npad->sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_left_lifo_state.sampling_number =
- npad->sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_right_lifo_state.sampling_number =
- npad->sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
-
- if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
- // This buffer only is updated on handheld on HW
- npad->sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
- } else {
- // Handheld doesn't update this buffer on HW
- npad->sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
- }
-
- npad->sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
- npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
- npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
- npad->sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
- }
-}
-
-void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
+void NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
hid_core.SetSupportedStyleTag(style_set);
if (is_controller_initialized) {
@@ -750,14 +574,14 @@ void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
is_controller_initialized = true;
}
-Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const {
+Core::HID::NpadStyleTag NPad::GetSupportedStyleSet() const {
if (!is_controller_initialized) {
return {Core::HID::NpadStyleSet::None};
}
return hid_core.GetSupportedStyleTag();
}
-Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
+Result NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
constexpr std::size_t max_number_npad_ids = 0xa;
const auto length = data.size();
ASSERT(length > 0 && (length % sizeof(u32)) == 0);
@@ -773,17 +597,17 @@ Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
return ResultSuccess;
}
-void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
+void NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
const auto copy_amount = supported_npad_id_types.size() * sizeof(u32);
ASSERT(max_length <= copy_amount);
std::memcpy(data, supported_npad_id_types.data(), copy_amount);
}
-std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const {
+std::size_t NPad::GetSupportedNpadIdTypesSize() const {
return supported_npad_id_types.size();
}
-void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
+void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
if (joy_hold_type != NpadJoyHoldType::Horizontal &&
joy_hold_type != NpadJoyHoldType::Vertical) {
LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}",
@@ -793,11 +617,11 @@ void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
hold_type = joy_hold_type;
}
-Controller_NPad::NpadJoyHoldType Controller_NPad::GetHoldType() const {
+NPad::NpadJoyHoldType NPad::GetHoldType() const {
return hold_type;
}
-void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
+void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
return;
@@ -806,21 +630,20 @@ void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode a
handheld_activation_mode = activation_mode;
}
-Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActivationMode() const {
+NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const {
return handheld_activation_mode;
}
-void Controller_NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
+void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
communication_mode = communication_mode_;
}
-Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode() const {
+NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const {
return communication_mode;
}
-bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
- NpadJoyDeviceType npad_device_type,
- NpadJoyAssignmentMode assignment_mode) {
+bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
+ NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return false;
@@ -889,9 +712,8 @@ bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID:
return true;
}
-bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
- std::size_t device_index,
- const Core::HID::VibrationValue& vibration_value) {
+bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
+ const Core::HID::VibrationValue& vibration_value) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!controller.device->IsConnected()) {
return false;
@@ -935,10 +757,9 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
return controller.device->SetVibration(device_index, vibration);
}
-void Controller_NPad::VibrateController(
- const Core::HID::VibrationDeviceHandle& vibration_device_handle,
- const Core::HID::VibrationValue& vibration_value) {
- if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
+void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle,
+ const Core::HID::VibrationValue& vibration_value) {
+ if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
return;
}
@@ -982,7 +803,7 @@ void Controller_NPad::VibrateController(
}
}
-void Controller_NPad::VibrateControllers(
+void NPad::VibrateControllers(
std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
std::span<const Core::HID::VibrationValue> vibration_values) {
if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
@@ -999,9 +820,9 @@ void Controller_NPad::VibrateControllers(
}
}
-Core::HID::VibrationValue Controller_NPad::GetLastVibration(
+Core::HID::VibrationValue NPad::GetLastVibration(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
+ if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
return {};
}
@@ -1010,9 +831,9 @@ Core::HID::VibrationValue Controller_NPad::GetLastVibration(
return controller.vibration[device_index].latest_vibration_value;
}
-void Controller_NPad::InitializeVibrationDevice(
+void NPad::InitializeVibrationDevice(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) {
- if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
+ if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
return;
}
@@ -1021,8 +842,8 @@ void Controller_NPad::InitializeVibrationDevice(
InitializeVibrationDeviceAtIndex(npad_index, device_index);
}
-void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
- std::size_t device_index) {
+void NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
+ std::size_t device_index) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!Settings::values.vibration_enabled.GetValue()) {
controller.vibration[device_index].device_mounted = false;
@@ -1033,13 +854,13 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa
controller.device->IsVibrationEnabled(device_index);
}
-void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
+void NPad::SetPermitVibrationSession(bool permit_vibration_session) {
permit_vibration_session_enabled = permit_vibration_session;
}
-bool Controller_NPad::IsVibrationDeviceMounted(
+bool NPad::IsVibrationDeviceMounted(
const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
+ if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
return false;
}
@@ -1048,7 +869,7 @@ bool Controller_NPad::IsVibrationDeviceMounted(
return controller.vibration[device_index].device_mounted;
}
-Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) {
+Kernel::KReadableEvent& NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
// Fallback to player 1
@@ -1060,18 +881,17 @@ Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::Npad
return controller.styleset_changed_event->GetReadableEvent();
}
-void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
+void NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
const auto& controller = GetControllerFromNpadIdType(npad_id);
controller.styleset_changed_event->Signal();
}
-void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller,
- Core::HID::NpadIdType npad_id) {
+void NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id) {
UpdateControllerAt(controller, npad_id, true);
}
-void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type,
- Core::HID::NpadIdType npad_id, bool connected) {
+void NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, Core::HID::NpadIdType npad_id,
+ bool connected) {
auto& controller = GetControllerFromNpadIdType(npad_id);
if (!connected) {
DisconnectNpad(npad_id);
@@ -1082,7 +902,7 @@ void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type,
InitNewlyAddedController(npad_id);
}
-Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
+Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -1108,9 +928,9 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
shared_memory->sixaxis_dual_right_properties.raw = 0;
shared_memory->sixaxis_left_properties.raw = 0;
shared_memory->sixaxis_right_properties.raw = 0;
- shared_memory->battery_level_dual = 0;
- shared_memory->battery_level_left = 0;
- shared_memory->battery_level_right = 0;
+ shared_memory->battery_level_dual = Core::HID::NpadBatteryLevel::Empty;
+ shared_memory->battery_level_left = Core::HID::NpadBatteryLevel::Empty;
+ shared_memory->battery_level_right = Core::HID::NpadBatteryLevel::Empty;
shared_memory->fullkey_color = {
.attribute = ColorAttribute::NoController,
.fullkey = {},
@@ -1131,54 +951,9 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
return ResultSuccess;
}
-Result Controller_NPad::SetGyroscopeZeroDriftMode(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode drift_mode) {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- auto& controller = GetControllerFromHandle(sixaxis_handle);
- sixaxis.gyroscope_zero_drift_mode = drift_mode;
- controller.device->SetGyroscopeZeroDriftMode(drift_mode);
-
- return ResultSuccess;
-}
-
-Result Controller_NPad::GetGyroscopeZeroDriftMode(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- drift_mode = sixaxis.gyroscope_zero_drift_mode;
-
- return ResultSuccess;
-}
-
-Result Controller_NPad::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool& is_at_rest) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& controller = GetControllerFromHandle(sixaxis_handle);
- is_at_rest = controller.sixaxis_at_rest;
- return ResultSuccess;
-}
-
-Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
+Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
@@ -1189,65 +964,9 @@ Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
return ResultSuccess;
}
-Result Controller_NPad::EnableSixAxisSensorUnalteredPassthrough(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- sixaxis.unaltered_passtrough = is_enabled;
- return ResultSuccess;
-}
-
-Result Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- is_enabled = sixaxis.unaltered_passtrough;
- return ResultSuccess;
-}
-
-Result Controller_NPad::LoadSixAxisSensorCalibrationParameter(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- // TODO: Request this data to the controller. On error return 0xd8ca
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- calibration = sixaxis.calibration;
- return ResultSuccess;
-}
-
-Result Controller_NPad::GetSixAxisSensorIcInformation(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorIcInformation& ic_information) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- // TODO: Request this data to the controller. On error return 0xd8ca
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- ic_information = sixaxis.ic_information;
- return ResultSuccess;
-}
-
-Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
+Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
return is_valid;
@@ -1259,83 +978,32 @@ Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
return ResultSuccess;
}
-Result Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool sixaxis_status) {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& controller = GetControllerFromHandle(sixaxis_handle);
- controller.sixaxis_sensor_enabled = sixaxis_status;
- return ResultSuccess;
+NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) {
+ return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo;
}
-Result Controller_NPad::IsSixAxisSensorFusionEnabled(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- is_fusion_enabled = sixaxis.is_fusion_enabled;
-
- return ResultSuccess;
+NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) {
+ return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo;
}
-Result Controller_NPad::SetSixAxisFusionEnabled(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- sixaxis.is_fusion_enabled = is_fusion_enabled;
-
- return ResultSuccess;
+NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) {
+ return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo;
}
-Result Controller_NPad::SetSixAxisFusionParameters(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto param1 = sixaxis_fusion_parameters.parameter1;
- if (param1 < 0.0f || param1 > 1.0f) {
- return InvalidSixAxisFusionRange;
- }
-
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- sixaxis.fusion = sixaxis_fusion_parameters;
-
- return ResultSuccess;
+NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) {
+ return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo;
}
-Result Controller_NPad::GetSixAxisFusionParameters(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters& parameters) const {
- const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- parameters = sixaxis.fusion;
+NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) {
+ return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo;
+}
- return ResultSuccess;
+NPad::SixAxisLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) {
+ return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo;
}
-Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
- Core::HID::NpadIdType npad_id_2) {
+Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
+ Core::HID::NpadIdType npad_id_2) {
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
npad_id_2);
@@ -1397,18 +1065,17 @@ Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
return ResultSuccess;
}
-void Controller_NPad::StartLRAssignmentMode() {
+void NPad::StartLRAssignmentMode() {
// Nothing internally is used for lr assignment mode. Since we have the ability to set the
// controller types from boot, it doesn't really matter about showing a selection screen
is_in_lr_assignment_mode = true;
}
-void Controller_NPad::StopLRAssignmentMode() {
+void NPad::StopLRAssignmentMode() {
is_in_lr_assignment_mode = false;
}
-Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
- Core::HID::NpadIdType npad_id_2) {
+Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2) {
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
npad_id_2);
@@ -1439,8 +1106,7 @@ Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
return ResultSuccess;
}
-Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id,
- Core::HID::LedPattern& pattern) const {
+Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -1450,8 +1116,8 @@ Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id,
return ResultSuccess;
}
-Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
- bool& is_valid) const {
+Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
+ bool& is_valid) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -1461,8 +1127,8 @@ Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::
return ResultSuccess;
}
-Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(
- bool is_protection_enabled, Core::HID::NpadIdType npad_id) {
+Result NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
+ Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
return InvalidNpadId;
@@ -1472,11 +1138,11 @@ Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(
return ResultSuccess;
}
-void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
+void NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
analog_stick_use_center_clamp = use_center_clamp;
}
-void Controller_NPad::ClearAllConnectedControllers() {
+void NPad::ClearAllConnectedControllers() {
for (auto& controller : controller_data) {
if (controller.device->IsConnected() &&
controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) {
@@ -1486,13 +1152,13 @@ void Controller_NPad::ClearAllConnectedControllers() {
}
}
-void Controller_NPad::DisconnectAllConnectedControllers() {
+void NPad::DisconnectAllConnectedControllers() {
for (auto& controller : controller_data) {
controller.device->Disconnect();
}
}
-void Controller_NPad::ConnectAllDisconnectedControllers() {
+void NPad::ConnectAllDisconnectedControllers() {
for (auto& controller : controller_data) {
if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None &&
!controller.device->IsConnected()) {
@@ -1501,18 +1167,18 @@ void Controller_NPad::ConnectAllDisconnectedControllers() {
}
}
-void Controller_NPad::ClearAllControllers() {
+void NPad::ClearAllControllers() {
for (auto& controller : controller_data) {
controller.device->Disconnect();
controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
}
}
-Core::HID::NpadButton Controller_NPad::GetAndResetPressState() {
+Core::HID::NpadButton NPad::GetAndResetPressState() {
return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
}
-void Controller_NPad::ApplyNpadSystemCommonPolicy() {
+void NPad::ApplyNpadSystemCommonPolicy() {
Core::HID::NpadStyleTag styletag{};
styletag.fullkey.Assign(1);
styletag.handheld.Assign(1);
@@ -1537,7 +1203,7 @@ void Controller_NPad::ApplyNpadSystemCommonPolicy() {
supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
}
-bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
+bool NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
if (controller == Core::HID::NpadStyleIndex::Handheld) {
const bool support_handheld =
std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
@@ -1588,51 +1254,50 @@ bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller
return false;
}
-Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) {
+NPad::NpadControllerData& NPad::GetControllerFromHandle(
+ const Core::HID::VibrationDeviceHandle& device_handle) {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
-const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) const {
+const NPad::NpadControllerData& NPad::GetControllerFromHandle(
+ const Core::HID::VibrationDeviceHandle& device_handle) const {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
-Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
- const Core::HID::VibrationDeviceHandle& device_handle) {
+NPad::NpadControllerData& NPad::GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle) {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
-const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
- const Core::HID::VibrationDeviceHandle& device_handle) const {
+const NPad::NpadControllerData& NPad::GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle) const {
const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
return GetControllerFromNpadIdType(npad_id);
}
-Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType(
- Core::HID::NpadIdType npad_id) {
+NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
npad_id = Core::HID::NpadIdType::Player1;
}
- const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id);
+ const auto npad_index = NpadIdTypeToIndex(npad_id);
return controller_data[npad_index];
}
-const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType(
+const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(
Core::HID::NpadIdType npad_id) const {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
npad_id = Core::HID::NpadIdType::Player1;
}
- const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id);
+ const auto npad_index = NpadIdTypeToIndex(npad_id);
return controller_data[npad_index];
}
-Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
+Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
@@ -1655,7 +1320,7 @@ Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
}
}
-const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
+const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
const auto& controller = GetControllerFromHandle(sixaxis_handle);
switch (sixaxis_handle.npad_type) {
@@ -1678,50 +1343,13 @@ const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
}
}
-Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
- auto& controller = GetControllerFromHandle(sixaxis_handle);
- switch (sixaxis_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Pokeball:
- return controller.sixaxis_fullkey;
- case Core::HID::NpadStyleIndex::Handheld:
- return controller.sixaxis_handheld;
- case Core::HID::NpadStyleIndex::JoyconDual:
- if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
- return controller.sixaxis_dual_left;
- }
- return controller.sixaxis_dual_right;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- return controller.sixaxis_left;
- case Core::HID::NpadStyleIndex::JoyconRight:
- return controller.sixaxis_right;
- default:
- return controller.sixaxis_unknown;
- }
-}
+NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) {
+ const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory;
-const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
- const auto& controller = GetControllerFromHandle(sixaxis_handle);
- switch (sixaxis_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Pokeball:
- return controller.sixaxis_fullkey;
- case Core::HID::NpadStyleIndex::Handheld:
- return controller.sixaxis_handheld;
- case Core::HID::NpadStyleIndex::JoyconDual:
- if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
- return controller.sixaxis_dual_left;
- }
- return controller.sixaxis_dual_right;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- return controller.sixaxis_left;
- case Core::HID::NpadStyleIndex::JoyconRight:
- return controller.sixaxis_right;
- default:
- return controller.sixaxis_unknown;
- }
+ return {
+ .ui_variant = 0,
+ .footer = shared_memory->applet_footer_type,
+ };
}
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 949e58a4c..9167c93f0 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -10,7 +10,6 @@
#include "common/bit_field.h"
#include "common/common_types.h"
-#include "common/vector_math.h"
#include "core/hid/hid_types.h"
#include "core/hle/service/hid/controllers/controller_base.h"
@@ -34,11 +33,11 @@ union Result;
namespace Service::HID {
-class Controller_NPad final : public ControllerBase {
+class NPad final : public ControllerBase {
public:
- explicit Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
- KernelHelpers::ServiceContext& service_context_);
- ~Controller_NPad() override;
+ explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
+ KernelHelpers::ServiceContext& service_context_);
+ ~NPad() override;
// Called when the controller is initialized
void OnInit() override;
@@ -49,9 +48,6 @@ public:
// When the controller is requesting an update for the shared memory
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
- // When the controller is requesting a motion update for the shared memory
- void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
// This is nn::hid::NpadJoyHoldType
enum class NpadJoyHoldType : u64 {
Vertical = 0,
@@ -78,6 +74,46 @@ public:
MaxActivationMode = 3,
};
+ // This is nn::hid::system::AppletFooterUiAttributesSet
+ struct AppletFooterUiAttributes {
+ INSERT_PADDING_BYTES(0x4);
+ };
+
+ // This is nn::hid::system::AppletFooterUiType
+ enum class AppletFooterUiType : u8 {
+ None = 0,
+ HandheldNone = 1,
+ HandheldJoyConLeftOnly = 2,
+ HandheldJoyConRightOnly = 3,
+ HandheldJoyConLeftJoyConRight = 4,
+ JoyDual = 5,
+ JoyDualLeftOnly = 6,
+ JoyDualRightOnly = 7,
+ JoyLeftHorizontal = 8,
+ JoyLeftVertical = 9,
+ JoyRightHorizontal = 10,
+ JoyRightVertical = 11,
+ SwitchProController = 12,
+ CompatibleProController = 13,
+ CompatibleJoyCon = 14,
+ LarkHvc1 = 15,
+ LarkHvc2 = 16,
+ LarkNesLeft = 17,
+ LarkNesRight = 18,
+ Lucia = 19,
+ Verification = 20,
+ Lagon = 21,
+ };
+
+ using AppletFooterUiVariant = u8;
+
+ // This is "nn::hid::system::AppletDetailedUiType".
+ struct AppletDetailedUiType {
+ AppletFooterUiVariant ui_variant;
+ INSERT_PADDING_BYTES(0x2);
+ AppletFooterUiType footer;
+ };
+ static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size");
// This is nn::hid::NpadCommunicationMode
enum class NpadCommunicationMode : u64 {
Mode_5ms = 0,
@@ -86,6 +122,15 @@ public:
Default = 3,
};
+ enum class NpadRevision : u32 {
+ Revision0 = 0,
+ Revision1 = 1,
+ Revision2 = 2,
+ Revision3 = 3,
+ };
+
+ using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>;
+
void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
Core::HID::NpadStyleTag GetSupportedStyleSet() const;
@@ -138,37 +183,18 @@ public:
Result DisconnectNpad(Core::HID::NpadIdType npad_id);
- Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode drift_mode);
- Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
- Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool& is_at_rest) const;
Result IsFirmwareUpdateAvailableForSixAxisSensor(
const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const;
- Result EnableSixAxisSensorUnalteredPassthrough(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
- Result IsSixAxisSensorUnalteredPassthroughEnabled(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
- Result LoadSixAxisSensorCalibrationParameter(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
- Result GetSixAxisSensorIcInformation(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorIcInformation& ic_information) const;
Result ResetIsSixAxisSensorDeviceNewlyAssigned(
const Core::HID::SixAxisSensorHandle& sixaxis_handle);
- Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool sixaxis_status);
- Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool& is_fusion_enabled) const;
- Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool is_fusion_enabled);
- Result SetSixAxisFusionParameters(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
- Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters& parameters) const;
+
+ SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id);
+ SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id);
+ SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id);
+ SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id);
+ SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id);
+ SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id);
+
Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
bool& is_enabled) const;
@@ -192,10 +218,7 @@ public:
void ApplyNpadSystemCommonPolicy();
- static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
- static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
- static Result VerifyValidSixAxisSensorHandle(
- const Core::HID::SixAxisSensorHandle& device_handle);
+ AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
private:
static constexpr std::size_t NPAD_COUNT = 10;
@@ -254,29 +277,6 @@ private:
};
static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
- // This is nn::hid::SixAxisSensorAttribute
- struct SixAxisSensorAttribute {
- union {
- u32 raw{};
- BitField<0, 1, u32> is_connected;
- BitField<1, 1, u32> is_interpolated;
- };
- };
- static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
-
- // This is nn::hid::SixAxisSensorState
- struct SixAxisSensorState {
- s64 delta_time{};
- s64 sampling_number{};
- Common::Vec3f accel{};
- Common::Vec3f gyro{};
- Common::Vec3f rotation{};
- std::array<Common::Vec3f, 3> orientation{};
- SixAxisSensorAttribute attribute{};
- INSERT_PADDING_BYTES(4); // Reserved
- };
- static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
-
// This is nn::hid::server::NpadGcTriggerState
struct NpadGcTriggerState {
s64 sampling_number{};
@@ -353,37 +353,6 @@ private:
static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
"NfcXcdDeviceHandleStateImpl is an invalid size");
- // This is nn::hid::system::AppletFooterUiAttributesSet
- struct AppletFooterUiAttributes {
- INSERT_PADDING_BYTES(0x4);
- };
-
- // This is nn::hid::system::AppletFooterUiType
- enum class AppletFooterUiType : u8 {
- None = 0,
- HandheldNone = 1,
- HandheldJoyConLeftOnly = 2,
- HandheldJoyConRightOnly = 3,
- HandheldJoyConLeftJoyConRight = 4,
- JoyDual = 5,
- JoyDualLeftOnly = 6,
- JoyDualRightOnly = 7,
- JoyLeftHorizontal = 8,
- JoyLeftVertical = 9,
- JoyRightHorizontal = 10,
- JoyRightVertical = 11,
- SwitchProController = 12,
- CompatibleProController = 13,
- CompatibleJoyCon = 14,
- LarkHvc1 = 15,
- LarkHvc2 = 16,
- LarkNesLeft = 17,
- LarkNesRight = 18,
- Lucia = 19,
- Verification = 20,
- Lagon = 21,
- };
-
// This is nn::hid::NpadLarkType
enum class NpadLarkType : u32 {
Invalid,
@@ -427,12 +396,12 @@ private:
Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{};
Lifo<NPadGenericState, hid_entry_count> palma_lifo{};
Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{};
- Lifo<SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{};
- Lifo<SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{};
- Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{};
- Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{};
- Lifo<SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{};
- Lifo<SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{};
+ Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{};
+ Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{};
+ Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{};
+ Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{};
+ Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{};
+ Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{};
DeviceType device_type{};
INSERT_PADDING_BYTES(0x4); // Reserved
NPadSystemProperties system_properties{};
@@ -466,16 +435,6 @@ private:
std::chrono::steady_clock::time_point last_vibration_timepoint{};
};
- struct SixaxisParameters {
- bool is_fusion_enabled{true};
- bool unaltered_passtrough{false};
- Core::HID::SixAxisSensorFusionParameters fusion{};
- Core::HID::SixAxisSensorCalibrationParameter calibration{};
- Core::HID::SixAxisSensorIcInformation ic_information{};
- Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
- Core::HID::GyroscopeZeroDriftMode::Standard};
- };
-
struct NpadControllerData {
Kernel::KEvent* styleset_changed_event{};
NpadInternalState* shared_memory = nullptr;
@@ -489,27 +448,10 @@ private:
bool is_dual_left_connected{true};
bool is_dual_right_connected{true};
- // Motion parameters
- bool sixaxis_at_rest{true};
- bool sixaxis_sensor_enabled{true};
- SixaxisParameters sixaxis_fullkey{};
- SixaxisParameters sixaxis_handheld{};
- SixaxisParameters sixaxis_dual_left{};
- SixaxisParameters sixaxis_dual_right{};
- SixaxisParameters sixaxis_left{};
- SixaxisParameters sixaxis_right{};
- SixaxisParameters sixaxis_unknown{};
-
// Current pad state
NPadGenericState npad_pad_state{};
NPadGenericState npad_libnx_state{};
NpadGcTriggerState npad_trigger_state{};
- SixAxisSensorState sixaxis_fullkey_state{};
- SixAxisSensorState sixaxis_handheld_state{};
- SixAxisSensorState sixaxis_dual_left_state{};
- SixAxisSensorState sixaxis_dual_right_state{};
- SixAxisSensorState sixaxis_left_lifo_state{};
- SixAxisSensorState sixaxis_right_lifo_state{};
int callback_key{};
};
@@ -520,13 +462,13 @@ private:
void WriteEmptyEntry(NpadInternalState* npad);
NpadControllerData& GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle);
- const NpadControllerData& GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) const;
- NpadControllerData& GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle);
const NpadControllerData& GetControllerFromHandle(
const Core::HID::VibrationDeviceHandle& device_handle) const;
+ NpadControllerData& GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle);
+ const NpadControllerData& GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle) const;
NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
@@ -534,9 +476,6 @@ private:
const Core::HID::SixAxisSensorHandle& device_handle);
const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
const Core::HID::SixAxisSensorHandle& device_handle) const;
- SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
- const SixaxisParameters& GetSixaxisState(
- const Core::HID::SixAxisSensorHandle& device_handle) const;
std::atomic<u64> press_state{};
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index 73a2a2b91..588ff9d62 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -12,43 +12,43 @@
namespace Service::HID {
-Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
- KernelHelpers::ServiceContext& service_context_)
+Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
+ KernelHelpers::ServiceContext& service_context_)
: ControllerBase{hid_core_}, service_context{service_context_} {
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
}
-Controller_Palma::~Controller_Palma() {
+Palma::~Palma() {
service_context.CloseEvent(operation_complete_event);
};
-void Controller_Palma::OnInit() {}
+void Palma::OnInit() {}
-void Controller_Palma::OnRelease() {}
+void Palma::OnRelease() {}
-void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
return;
}
}
-Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
- PalmaConnectionHandle& handle) {
+Result Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
+ PalmaConnectionHandle& handle) {
active_handle.npad_id = npad_id;
handle = active_handle;
return ResultSuccess;
}
-Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) {
+Result Palma::InitializePalma(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
- ActivateController();
+ Activate();
return ResultSuccess;
}
-Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent(
+Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent(
const PalmaConnectionHandle& handle) const {
if (handle.npad_id != active_handle.npad_id) {
LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id);
@@ -56,9 +56,9 @@ Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent(
return operation_complete_event->GetReadableEvent();
}
-Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
- PalmaOperationType& operation_type,
- PalmaOperationData& data) const {
+Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
+ PalmaOperationType& operation_type,
+ PalmaOperationData& data) const {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -67,8 +67,7 @@ Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& hand
return ResultSuccess;
}
-Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
- u64 palma_activity) {
+Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -79,8 +78,7 @@ Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
return ResultSuccess;
}
-Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle,
- PalmaFrModeType fr_mode_) {
+Result Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -88,7 +86,7 @@ Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle,
return ResultSuccess;
}
-Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
+Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -99,25 +97,25 @@ Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
return ResultSuccess;
}
-Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
+Result Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
return ResultSuccess;
}
-Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
+Result Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
return ResultSuccess;
}
-void Controller_Palma::ReadPalmaApplicationSection() {}
+void Palma::ReadPalmaApplicationSection() {}
-void Controller_Palma::WritePalmaApplicationSection() {}
+void Palma::WritePalmaApplicationSection() {}
-Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
+Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -128,7 +126,7 @@ Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle
return ResultSuccess;
}
-Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
+Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -139,10 +137,9 @@ Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle&
return ResultSuccess;
}
-void Controller_Palma::WritePalmaActivityEntry() {}
+void Palma::WritePalmaActivityEntry() {}
-Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle,
- u64 unknown) {
+Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -153,8 +150,8 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
return ResultSuccess;
}
-Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
- Common::ProcessAddress t_mem, u64 size) {
+Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
+ Common::ProcessAddress t_mem, u64 size) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -165,8 +162,8 @@ Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle
return ResultSuccess;
}
-Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
- s32 database_id_version_) {
+Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
+ s32 database_id_version_) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -178,8 +175,7 @@ Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnec
return ResultSuccess;
}
-Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
- const PalmaConnectionHandle& handle) {
+Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -191,26 +187,26 @@ Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
return ResultSuccess;
}
-void Controller_Palma::SuspendPalmaFeature() {}
+void Palma::SuspendPalmaFeature() {}
-Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
+Result Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
return operation.result;
}
-void Controller_Palma::ReadPalmaPlayLog() {}
+void Palma::ReadPalmaPlayLog() {}
-void Controller_Palma::ResetPalmaPlayLog() {}
+void Palma::ResetPalmaPlayLog() {}
-void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
+void Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
// If true controllers are able to be paired
is_connectable = is_all_connectable;
}
-void Controller_Palma::SetIsPalmaPairedConnectable() {}
+void Palma::SetIsPalmaPairedConnectable() {}
-Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) {
+Result Palma::PairPalma(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
@@ -218,14 +214,14 @@ Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) {
return ResultSuccess;
}
-void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {}
+void Palma::SetPalmaBoostMode(bool boost_mode) {}
-void Controller_Palma::CancelWritePalmaWaveEntry() {}
+void Palma::CancelWritePalmaWaveEntry() {}
-void Controller_Palma::EnablePalmaBoostMode() {}
+void Palma::EnablePalmaBoostMode() {}
-void Controller_Palma::GetPalmaBluetoothAddress() {}
+void Palma::GetPalmaBluetoothAddress() {}
-void Controller_Palma::SetDisallowedPalmaConnection() {}
+void Palma::SetDisallowedPalmaConnection() {}
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
index a0491a819..a6047f36a 100644
--- a/src/core/hle/service/hid/controllers/palma.h
+++ b/src/core/hle/service/hid/controllers/palma.h
@@ -23,7 +23,7 @@ class EmulatedController;
} // namespace Core::HID
namespace Service::HID {
-class Controller_Palma final : public ControllerBase {
+class Palma final : public ControllerBase {
public:
using PalmaOperationData = std::array<u8, 0x140>;
@@ -97,9 +97,9 @@ public:
static_assert(sizeof(PalmaConnectionHandle) == 0x8,
"PalmaConnectionHandle has incorrect size.");
- explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
- KernelHelpers::ServiceContext& service_context_);
- ~Controller_Palma() override;
+ explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
+ KernelHelpers::ServiceContext& service_context_);
+ ~Palma() override;
// Called when the controller is initialized
void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/seven_six_axis.cpp
index bcb272eaf..495568484 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/seven_six_axis.cpp
@@ -1,32 +1,29 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+#include <cstring>
+#include "common/common_types.h"
#include "core/core.h"
#include "core/core_timing.h"
+#include "core/frontend/emu_window.h"
#include "core/hid/emulated_console.h"
+#include "core/hid/emulated_devices.h"
#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/console_sixaxis.h"
+#include "core/hle/service/hid/controllers/seven_six_axis.h"
#include "core/memory.h"
namespace Service::HID {
-constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
-
-Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_)
+SevenSixAxis::SevenSixAxis(Core::System& system_)
: ControllerBase{system_.HIDCore()}, system{system_} {
console = hid_core.GetEmulatedConsole();
- static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
- "ConsoleSharedMemory is bigger than the shared memory");
- shared_memory = std::construct_at(
- reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
}
-Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default;
-
-void Controller_ConsoleSixAxis::OnInit() {}
+SevenSixAxis::~SevenSixAxis() = default;
-void Controller_ConsoleSixAxis::OnRelease() {}
+void SevenSixAxis::OnInit() {}
+void SevenSixAxis::OnRelease() {}
-void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void SevenSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated() || transfer_memory == 0) {
seven_sixaxis_lifo.buffer_count = 0;
seven_sixaxis_lifo.buffer_tail = 0;
@@ -53,22 +50,17 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
-motion_status.quaternion.xyz.z,
};
- shared_memory->sampling_number++;
- shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
- shared_memory->verticalization_error = motion_status.verticalization_error;
- shared_memory->gyro_bias = motion_status.gyro_bias;
-
- // Update seven six axis transfer memory
seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo,
sizeof(seven_sixaxis_lifo));
}
-void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
+void SevenSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
transfer_memory = t_mem;
}
-void Controller_ConsoleSixAxis::ResetTimestamp() {
+void SevenSixAxis::ResetTimestamp() {
last_saved_timestamp = last_global_timestamp;
}
+
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/seven_six_axis.h
index 7015d924c..40e3f5d12 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/seven_six_axis.h
@@ -1,10 +1,9 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
-#include <array>
-
+#include "common/common_types.h"
#include "common/quaternion.h"
#include "common/typed_address.h"
#include "core/hle/service/hid/controllers/controller_base.h"
@@ -19,10 +18,10 @@ class EmulatedConsole;
} // namespace Core::HID
namespace Service::HID {
-class Controller_ConsoleSixAxis final : public ControllerBase {
+class SevenSixAxis final : public ControllerBase {
public:
- explicit Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_);
- ~Controller_ConsoleSixAxis() override;
+ explicit SevenSixAxis(Core::System& system_);
+ ~SevenSixAxis() override;
// Called when the controller is initialized
void OnInit() override;
@@ -51,28 +50,16 @@ private:
};
static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size");
- // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
- struct ConsoleSharedMemory {
- u64 sampling_number{};
- bool is_seven_six_axis_sensor_at_rest{};
- INSERT_PADDING_BYTES(3); // padding
- f32 verticalization_error{};
- Common::Vec3f gyro_bias{};
- INSERT_PADDING_BYTES(4); // padding
- };
- static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
-
Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
+ u64 last_saved_timestamp{};
+ u64 last_global_timestamp{};
+
SevenSixAxisState next_seven_sixaxis_state{};
Common::ProcessAddress transfer_memory{};
- ConsoleSharedMemory* shared_memory = nullptr;
Core::HID::EmulatedConsole* console = nullptr;
- u64 last_saved_timestamp{};
- u64 last_global_timestamp{};
-
Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp
new file mode 100644
index 000000000..3d24a5c04
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/six_axis.cpp
@@ -0,0 +1,413 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/common_types.h"
+#include "core/core_timing.h"
+#include "core/hid/emulated_controller.h"
+#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/controllers/npad.h"
+#include "core/hle/service/hid/controllers/six_axis.h"
+#include "core/hle/service/hid/errors.h"
+#include "core/hle/service/hid/hid_util.h"
+
+namespace Service::HID {
+
+SixAxis::SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_)
+ : ControllerBase{hid_core_}, npad{npad_} {
+ for (std::size_t i = 0; i < controller_data.size(); ++i) {
+ auto& controller = controller_data[i];
+ controller.device = hid_core.GetEmulatedControllerByIndex(i);
+ }
+}
+
+SixAxis::~SixAxis() = default;
+
+void SixAxis::OnInit() {}
+void SixAxis::OnRelease() {}
+
+void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!IsControllerActivated()) {
+ return;
+ }
+
+ for (std::size_t i = 0; i < controller_data.size(); ++i) {
+ auto& controller = controller_data[i];
+
+ const auto npad_id = IndexToNpadIdType(i);
+ const auto& controller_type = controller.device->GetNpadStyleIndex();
+
+ if (controller_type == Core::HID::NpadStyleIndex::None ||
+ !controller.device->IsConnected()) {
+ continue;
+ }
+
+ const auto& motion_state = controller.device->GetMotions();
+ auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
+ auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
+ auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
+ auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
+ auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
+ auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
+
+ auto& sixaxis_fullkey_lifo = npad->GetSixAxisFullkeyLifo(npad_id);
+ auto& sixaxis_handheld_lifo = npad->GetSixAxisHandheldLifo(npad_id);
+ auto& sixaxis_dual_left_lifo = npad->GetSixAxisDualLeftLifo(npad_id);
+ auto& sixaxis_dual_right_lifo = npad->GetSixAxisDualRightLifo(npad_id);
+ auto& sixaxis_left_lifo = npad->GetSixAxisLeftLifo(npad_id);
+ auto& sixaxis_right_lifo = npad->GetSixAxisRightLifo(npad_id);
+
+ // Clear previous state
+ sixaxis_fullkey_state = {};
+ sixaxis_handheld_state = {};
+ sixaxis_dual_left_state = {};
+ sixaxis_dual_right_state = {};
+ sixaxis_left_lifo_state = {};
+ sixaxis_right_lifo_state = {};
+
+ if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
+ controller.sixaxis_at_rest = true;
+ for (std::size_t e = 0; e < motion_state.size(); ++e) {
+ controller.sixaxis_at_rest =
+ controller.sixaxis_at_rest && motion_state[e].is_at_rest;
+ }
+ }
+
+ const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state,
+ const Core::HID::ControllerMotion& hid_state) {
+ using namespace std::literals::chrono_literals;
+ static constexpr Core::HID::SixAxisSensorState default_motion_state = {
+ .delta_time = std::chrono::nanoseconds(5ms).count(),
+ .accel = {0, 0, -1.0f},
+ .orientation =
+ {
+ Common::Vec3f{1.0f, 0, 0},
+ Common::Vec3f{0, 1.0f, 0},
+ Common::Vec3f{0, 0, 1.0f},
+ },
+ .attribute = {1},
+ };
+ if (!controller.sixaxis_sensor_enabled) {
+ state = default_motion_state;
+ return;
+ }
+ if (!Settings::values.motion_enabled.GetValue()) {
+ state = default_motion_state;
+ return;
+ }
+ state.attribute.is_connected.Assign(1);
+ state.delta_time = std::chrono::nanoseconds(5ms).count();
+ state.accel = hid_state.accel;
+ state.gyro = hid_state.gyro;
+ state.rotation = hid_state.rotation;
+ state.orientation = hid_state.orientation;
+ };
+
+ switch (controller_type) {
+ case Core::HID::NpadStyleIndex::None:
+ ASSERT(false);
+ break;
+ case Core::HID::NpadStyleIndex::ProController:
+ set_motion_state(sixaxis_fullkey_state, motion_state[0]);
+ break;
+ case Core::HID::NpadStyleIndex::Handheld:
+ set_motion_state(sixaxis_handheld_state, motion_state[0]);
+ break;
+ case Core::HID::NpadStyleIndex::JoyconDual:
+ set_motion_state(sixaxis_dual_left_state, motion_state[0]);
+ set_motion_state(sixaxis_dual_right_state, motion_state[1]);
+ break;
+ case Core::HID::NpadStyleIndex::JoyconLeft:
+ set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
+ break;
+ case Core::HID::NpadStyleIndex::JoyconRight:
+ set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
+ break;
+ case Core::HID::NpadStyleIndex::Pokeball:
+ using namespace std::literals::chrono_literals;
+ set_motion_state(sixaxis_fullkey_state, motion_state[0]);
+ sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
+ break;
+ default:
+ break;
+ }
+
+ sixaxis_fullkey_state.sampling_number =
+ sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ sixaxis_handheld_state.sampling_number =
+ sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ sixaxis_dual_left_state.sampling_number =
+ sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ sixaxis_dual_right_state.sampling_number =
+ sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ sixaxis_left_lifo_state.sampling_number =
+ sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
+ sixaxis_right_lifo_state.sampling_number =
+ sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
+
+ if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
+ // This buffer only is updated on handheld on HW
+ sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
+ } else {
+ // Handheld doesn't update this buffer on HW
+ sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
+ }
+
+ sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
+ sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
+ sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
+ sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
+ }
+}
+
+Result SixAxis::SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::GyroscopeZeroDriftMode drift_mode) {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ auto& controller = GetControllerFromHandle(sixaxis_handle);
+ sixaxis.gyroscope_zero_drift_mode = drift_mode;
+ controller.device->SetGyroscopeZeroDriftMode(drift_mode);
+
+ return ResultSuccess;
+}
+
+Result SixAxis::GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ const auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ drift_mode = sixaxis.gyroscope_zero_drift_mode;
+
+ return ResultSuccess;
+}
+
+Result SixAxis::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool& is_at_rest) const {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ const auto& controller = GetControllerFromHandle(sixaxis_handle);
+ is_at_rest = controller.sixaxis_at_rest;
+ return ResultSuccess;
+}
+
+Result SixAxis::LoadSixAxisSensorCalibrationParameter(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ // TODO: Request this data to the controller. On error return 0xd8ca
+ const auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ calibration = sixaxis.calibration;
+ return ResultSuccess;
+}
+
+Result SixAxis::GetSixAxisSensorIcInformation(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorIcInformation& ic_information) const {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ // TODO: Request this data to the controller. On error return 0xd8ca
+ const auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ ic_information = sixaxis.ic_information;
+ return ResultSuccess;
+}
+
+Result SixAxis::EnableSixAxisSensorUnalteredPassthrough(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ sixaxis.unaltered_passtrough = is_enabled;
+ return ResultSuccess;
+}
+
+Result SixAxis::IsSixAxisSensorUnalteredPassthroughEnabled(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ const auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ is_enabled = sixaxis.unaltered_passtrough;
+ return ResultSuccess;
+}
+
+Result SixAxis::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool sixaxis_status) {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ auto& controller = GetControllerFromHandle(sixaxis_handle);
+ controller.sixaxis_sensor_enabled = sixaxis_status;
+ return ResultSuccess;
+}
+
+Result SixAxis::IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool& is_fusion_enabled) const {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ const auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ is_fusion_enabled = sixaxis.is_fusion_enabled;
+
+ return ResultSuccess;
+}
+Result SixAxis::SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool is_fusion_enabled) {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ sixaxis.is_fusion_enabled = is_fusion_enabled;
+
+ return ResultSuccess;
+}
+
+Result SixAxis::SetSixAxisFusionParameters(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ const auto param1 = sixaxis_fusion_parameters.parameter1;
+ if (param1 < 0.0f || param1 > 1.0f) {
+ return InvalidSixAxisFusionRange;
+ }
+
+ auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ sixaxis.fusion = sixaxis_fusion_parameters;
+
+ return ResultSuccess;
+}
+
+Result SixAxis::GetSixAxisFusionParameters(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorFusionParameters& parameters) const {
+ const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
+ if (is_valid.IsError()) {
+ LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+ return is_valid;
+ }
+
+ const auto& sixaxis = GetSixaxisState(sixaxis_handle);
+ parameters = sixaxis.fusion;
+
+ return ResultSuccess;
+}
+
+SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
+ auto& controller = GetControllerFromHandle(sixaxis_handle);
+ switch (sixaxis_handle.npad_type) {
+ case Core::HID::NpadStyleIndex::ProController:
+ case Core::HID::NpadStyleIndex::Pokeball:
+ return controller.sixaxis_fullkey;
+ case Core::HID::NpadStyleIndex::Handheld:
+ return controller.sixaxis_handheld;
+ case Core::HID::NpadStyleIndex::JoyconDual:
+ if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
+ return controller.sixaxis_dual_left;
+ }
+ return controller.sixaxis_dual_right;
+ case Core::HID::NpadStyleIndex::JoyconLeft:
+ return controller.sixaxis_left;
+ case Core::HID::NpadStyleIndex::JoyconRight:
+ return controller.sixaxis_right;
+ default:
+ return controller.sixaxis_unknown;
+ }
+}
+
+const SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
+ const auto& controller = GetControllerFromHandle(sixaxis_handle);
+ switch (sixaxis_handle.npad_type) {
+ case Core::HID::NpadStyleIndex::ProController:
+ case Core::HID::NpadStyleIndex::Pokeball:
+ return controller.sixaxis_fullkey;
+ case Core::HID::NpadStyleIndex::Handheld:
+ return controller.sixaxis_handheld;
+ case Core::HID::NpadStyleIndex::JoyconDual:
+ if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
+ return controller.sixaxis_dual_left;
+ }
+ return controller.sixaxis_dual_right;
+ case Core::HID::NpadStyleIndex::JoyconLeft:
+ return controller.sixaxis_left;
+ case Core::HID::NpadStyleIndex::JoyconRight:
+ return controller.sixaxis_right;
+ default:
+ return controller.sixaxis_unknown;
+ }
+}
+
+SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle) {
+ const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
+ return GetControllerFromNpadIdType(npad_id);
+}
+
+const SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle) const {
+ const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
+ return GetControllerFromNpadIdType(npad_id);
+}
+
+SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
+ if (!IsNpadIdValid(npad_id)) {
+ LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
+ npad_id = Core::HID::NpadIdType::Player1;
+ }
+ const auto npad_index = NpadIdTypeToIndex(npad_id);
+ return controller_data[npad_index];
+}
+
+const SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(
+ Core::HID::NpadIdType npad_id) const {
+ if (!IsNpadIdValid(npad_id)) {
+ LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
+ npad_id = Core::HID::NpadIdType::Player1;
+ }
+ const auto npad_index = NpadIdTypeToIndex(npad_id);
+ return controller_data[npad_index];
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/six_axis.h b/src/core/hle/service/hid/controllers/six_axis.h
new file mode 100644
index 000000000..4c4f5dc7b
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/six_axis.h
@@ -0,0 +1,111 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "common/common_types.h"
+#include "core/hid/hid_types.h"
+#include "core/hle/service/hid/controllers/controller_base.h"
+#include "core/hle/service/hid/ring_lifo.h"
+
+namespace Core::HID {
+class EmulatedController;
+} // namespace Core::HID
+
+namespace Service::HID {
+class NPad;
+
+class SixAxis final : public ControllerBase {
+public:
+ explicit SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_);
+ ~SixAxis() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+ Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::GyroscopeZeroDriftMode drift_mode);
+ Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
+ Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool& is_at_rest) const;
+ Result EnableSixAxisSensorUnalteredPassthrough(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
+ Result IsSixAxisSensorUnalteredPassthroughEnabled(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
+ Result LoadSixAxisSensorCalibrationParameter(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
+ Result GetSixAxisSensorIcInformation(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorIcInformation& ic_information) const;
+ Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool sixaxis_status);
+ Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool& is_fusion_enabled) const;
+ Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ bool is_fusion_enabled);
+ Result SetSixAxisFusionParameters(
+ const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
+ Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
+ Core::HID::SixAxisSensorFusionParameters& parameters) const;
+
+private:
+ static constexpr std::size_t NPAD_COUNT = 10;
+
+ struct SixaxisParameters {
+ bool is_fusion_enabled{true};
+ bool unaltered_passtrough{false};
+ Core::HID::SixAxisSensorFusionParameters fusion{};
+ Core::HID::SixAxisSensorCalibrationParameter calibration{};
+ Core::HID::SixAxisSensorIcInformation ic_information{};
+ Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
+ Core::HID::GyroscopeZeroDriftMode::Standard};
+ };
+
+ struct NpadControllerData {
+ Core::HID::EmulatedController* device = nullptr;
+
+ // Motion parameters
+ bool sixaxis_at_rest{true};
+ bool sixaxis_sensor_enabled{true};
+ SixaxisParameters sixaxis_fullkey{};
+ SixaxisParameters sixaxis_handheld{};
+ SixaxisParameters sixaxis_dual_left{};
+ SixaxisParameters sixaxis_dual_right{};
+ SixaxisParameters sixaxis_left{};
+ SixaxisParameters sixaxis_right{};
+ SixaxisParameters sixaxis_unknown{};
+
+ // Current pad state
+ Core::HID::SixAxisSensorState sixaxis_fullkey_state{};
+ Core::HID::SixAxisSensorState sixaxis_handheld_state{};
+ Core::HID::SixAxisSensorState sixaxis_dual_left_state{};
+ Core::HID::SixAxisSensorState sixaxis_dual_right_state{};
+ Core::HID::SixAxisSensorState sixaxis_left_lifo_state{};
+ Core::HID::SixAxisSensorState sixaxis_right_lifo_state{};
+ int callback_key{};
+ };
+
+ SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
+ const SixaxisParameters& GetSixaxisState(
+ const Core::HID::SixAxisSensorHandle& device_handle) const;
+
+ NpadControllerData& GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle);
+ const NpadControllerData& GetControllerFromHandle(
+ const Core::HID::SixAxisSensorHandle& device_handle) const;
+ NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
+ const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
+
+ std::shared_ptr<NPad> npad;
+ std::array<NpadControllerData, NPAD_COUNT> controller_data{};
+};
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index 3ef91df4b..3bcf0ee9f 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -15,8 +15,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
-Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_,
- u8* raw_shared_memory_)
+TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
: ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size,
"TouchSharedMemory is bigger than the shared memory");
@@ -25,13 +24,13 @@ Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_,
console = hid_core.GetEmulatedConsole();
}
-Controller_Touchscreen::~Controller_Touchscreen() = default;
+TouchScreen::~TouchScreen() = default;
-void Controller_Touchscreen::OnInit() {}
+void TouchScreen::OnInit() {}
-void Controller_Touchscreen::OnRelease() {}
+void TouchScreen::OnRelease() {}
-void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index dd00921fd..cd342ce91 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -14,10 +14,10 @@ class EmulatedConsole;
} // namespace Core::HID
namespace Service::HID {
-class Controller_Touchscreen final : public ControllerBase {
+class TouchScreen final : public ControllerBase {
public:
- explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
- ~Controller_Touchscreen() override;
+ explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
+ ~TouchScreen() override;
// Called when the controller is initialized
void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp
index 62119e2c5..0aaed1fa7 100644
--- a/src/core/hle/service/hid/controllers/xpad.cpp
+++ b/src/core/hle/service/hid/controllers/xpad.cpp
@@ -10,20 +10,19 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
-Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
- : ControllerBase{hid_core_} {
+XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} {
static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size,
"XpadSharedMemory is bigger than the shared memory");
shared_memory = std::construct_at(
reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
}
-Controller_XPad::~Controller_XPad() = default;
+XPad::~XPad() = default;
-void Controller_XPad::OnInit() {}
+void XPad::OnInit() {}
-void Controller_XPad::OnRelease() {}
+void XPad::OnRelease() {}
-void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
if (!IsControllerActivated()) {
shared_memory->basic_xpad_lifo.buffer_count = 0;
shared_memory->basic_xpad_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h
index d01dee5fc..9e63a317a 100644
--- a/src/core/hle/service/hid/controllers/xpad.h
+++ b/src/core/hle/service/hid/controllers/xpad.h
@@ -10,10 +10,10 @@
#include "core/hle/service/hid/ring_lifo.h"
namespace Service::HID {
-class Controller_XPad final : public ControllerBase {
+class XPad final : public ControllerBase {
public:
- explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
- ~Controller_XPad() override;
+ explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
+ ~XPad() override;
// Called when the controller is initialized
void OnInit() override;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 929dd5f03..1b7381d8d 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -1,2864 +1,39 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include <array>
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "common/settings.h"
-#include "core/core.h"
-#include "core/core_timing.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/k_shared_memory.h"
-#include "core/hle/kernel/k_transfer_memory.h"
-#include "core/hle/kernel/kernel.h"
-#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid.h"
+#include "core/hle/service/hid/hid_debug_server.h"
+#include "core/hle/service/hid/hid_firmware_settings.h"
+#include "core/hle/service/hid/hid_server.h"
+#include "core/hle/service/hid/hid_system_server.h"
#include "core/hle/service/hid/hidbus.h"
#include "core/hle/service/hid/irs.h"
+#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/hid/xcd.h"
-#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/server_manager.h"
-#include "core/memory.h"
-
-#include "core/hle/service/hid/controllers/console_sixaxis.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/debug_pad.h"
-#include "core/hle/service/hid/controllers/gesture.h"
-#include "core/hle/service/hid/controllers/keyboard.h"
-#include "core/hle/service/hid/controllers/mouse.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/palma.h"
-#include "core/hle/service/hid/controllers/stubbed.h"
-#include "core/hle/service/hid/controllers/touchscreen.h"
-#include "core/hle/service/hid/controllers/xpad.h"
namespace Service::HID {
-// Updating period for each HID device.
-// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
-// Correct npad_update_ns is 4ms this is overclocked to lower input lag
-constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
-constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
-constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
-constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
-
-IAppletResource::IAppletResource(Core::System& system_,
- KernelHelpers::ServiceContext& service_context_)
- : ServiceFramework{system_, "IAppletResource"}, service_context{service_context_} {
- static const FunctionInfo functions[] = {
- {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
- };
- RegisterHandlers(functions);
- u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
- MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory);
- MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory);
- MakeController<Controller_Mouse>(HidController::Mouse, shared_memory);
- MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory);
- MakeController<Controller_XPad>(HidController::XPad, shared_memory);
- MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory);
- MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory);
- MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory);
- MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory);
- MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory);
- MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
- MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
- MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
- MakeController<Controller_Stubbed>(HidController::DebugMouse, shared_memory);
- MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory);
-
- // Homebrew doesn't try to activate some controllers, so we activate them by default
- GetController<Controller_NPad>(HidController::NPad).ActivateController();
- GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
-
- GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00);
- GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00);
- GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000);
- GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200);
- GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
- GetController<Controller_Stubbed>(HidController::DebugMouse).SetCommonHeaderOffset(0x3DC00);
-
- // Register update callbacks
- npad_update_event = Core::Timing::CreateEvent(
- "HID::UpdatePadCallback",
- [this](std::uintptr_t user_data, s64 time,
- std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- UpdateNpad(user_data, ns_late);
- return std::nullopt;
- });
- default_update_event = Core::Timing::CreateEvent(
- "HID::UpdateDefaultCallback",
- [this](std::uintptr_t user_data, s64 time,
- std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- UpdateControllers(user_data, ns_late);
- return std::nullopt;
- });
- mouse_keyboard_update_event = Core::Timing::CreateEvent(
- "HID::UpdateMouseKeyboardCallback",
- [this](std::uintptr_t user_data, s64 time,
- std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- UpdateMouseKeyboard(user_data, ns_late);
- return std::nullopt;
- });
- motion_update_event = Core::Timing::CreateEvent(
- "HID::UpdateMotionCallback",
- [this](std::uintptr_t user_data, s64 time,
- std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- UpdateMotion(user_data, ns_late);
- return std::nullopt;
- });
-
- system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
- system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
- default_update_event);
- system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
- mouse_keyboard_update_event);
- system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
- motion_update_event);
-
- system.HIDCore().ReloadInputDevices();
-}
-
-void IAppletResource::ActivateController(HidController controller) {
- controllers[static_cast<size_t>(controller)]->ActivateController();
-}
-
-void IAppletResource::DeactivateController(HidController controller) {
- controllers[static_cast<size_t>(controller)]->DeactivateController();
-}
-
-IAppletResource::~IAppletResource() {
- system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
- system.CoreTiming().UnscheduleEvent(default_update_event, 0);
- system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
- system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
-}
-
-void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
- LOG_DEBUG(Service_HID, "called");
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(&system.Kernel().GetHidSharedMem());
-}
-
-void IAppletResource::UpdateControllers(std::uintptr_t user_data,
- std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
-
- for (const auto& controller : controllers) {
- // Keyboard has it's own update event
- if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) {
- continue;
- }
- // Mouse has it's own update event
- if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
- continue;
- }
- // Npad has it's own update event
- if (controller == controllers[static_cast<size_t>(HidController::NPad)]) {
- continue;
- }
- controller->OnUpdate(core_timing);
- }
-}
-
-void IAppletResource::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
-
- controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing);
-}
-
-void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
- std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
-
- controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing);
- controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing);
-}
-
-void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
-
- controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing);
-}
-
-class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
-public:
- explicit IActiveVibrationDeviceList(Core::System& system_,
- std::shared_ptr<IAppletResource> applet_resource_)
- : ServiceFramework{system_, "IActiveVibrationDeviceList"},
- applet_resource(applet_resource_) {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
- }
-
-private:
- void InitializeVibrationDevice(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
-
- if (applet_resource != nullptr) {
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .InitializeVibrationDevice(vibration_device_handle);
- }
-
- LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
- vibration_device_handle.npad_type, vibration_device_handle.npad_id,
- vibration_device_handle.device_index);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
- }
-
- std::shared_ptr<IAppletResource> applet_resource;
-};
-
-std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
- if (applet_resource == nullptr) {
- applet_resource = std::make_shared<IAppletResource>(system, service_context);
- }
-
- return applet_resource;
-}
-
-Hid::Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_)
- : ServiceFramework{system_, "hid"}, applet_resource{applet_resource_}, service_context{
- system_,
- service_name} {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, &Hid::CreateAppletResource, "CreateAppletResource"},
- {1, &Hid::ActivateDebugPad, "ActivateDebugPad"},
- {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
- {21, &Hid::ActivateMouse, "ActivateMouse"},
- {26, nullptr, "ActivateDebugMouse"},
- {31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
- {32, &Hid::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"},
- {40, nullptr, "AcquireXpadIdEventHandle"},
- {41, nullptr, "ReleaseXpadIdEventHandle"},
- {51, &Hid::ActivateXpad, "ActivateXpad"},
- {55, &Hid::GetXpadIDs, "GetXpadIds"},
- {56, nullptr, "ActivateJoyXpad"},
- {58, nullptr, "GetJoyXpadLifoHandle"},
- {59, nullptr, "GetJoyXpadIds"},
- {60, &Hid::ActivateSixAxisSensor, "ActivateSixAxisSensor"},
- {61, &Hid::DeactivateSixAxisSensor, "DeactivateSixAxisSensor"},
- {62, nullptr, "GetSixAxisSensorLifoHandle"},
- {63, nullptr, "ActivateJoySixAxisSensor"},
- {64, nullptr, "DeactivateJoySixAxisSensor"},
- {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
- {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
- {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
- {68, &Hid::IsSixAxisSensorFusionEnabled, "IsSixAxisSensorFusionEnabled"},
- {69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
- {70, &Hid::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"},
- {71, &Hid::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"},
- {72, &Hid::ResetSixAxisSensorFusionParameters, "ResetSixAxisSensorFusionParameters"},
- {73, nullptr, "SetAccelerometerParameters"},
- {74, nullptr, "GetAccelerometerParameters"},
- {75, nullptr, "ResetAccelerometerParameters"},
- {76, nullptr, "SetAccelerometerPlayMode"},
- {77, nullptr, "GetAccelerometerPlayMode"},
- {78, nullptr, "ResetAccelerometerPlayMode"},
- {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
- {80, &Hid::GetGyroscopeZeroDriftMode, "GetGyroscopeZeroDriftMode"},
- {81, &Hid::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"},
- {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
- {83, &Hid::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"},
- {84, &Hid::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"},
- {85, &Hid::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"},
- {86, nullptr, "StoreSixAxisSensorCalibrationParameter"},
- {87, &Hid::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"},
- {88, &Hid::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"},
- {89, &Hid::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"},
- {91, &Hid::ActivateGesture, "ActivateGesture"},
- {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
- {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
- {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
- {103, &Hid::ActivateNpad, "ActivateNpad"},
- {104, &Hid::DeactivateNpad, "DeactivateNpad"},
- {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
- {107, &Hid::DisconnectNpad, "DisconnectNpad"},
- {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
- {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
- {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
- {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
- {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
- {123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"},
- {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
- {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
- {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
- {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
- {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
- {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
- {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
- {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
- {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
- {133, &Hid::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"},
- {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"},
- {135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"},
- {136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"},
- {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
- {201, &Hid::SendVibrationValue, "SendVibrationValue"},
- {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
- {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
- {204, &Hid::PermitVibration, "PermitVibration"},
- {205, &Hid::IsVibrationPermitted, "IsVibrationPermitted"},
- {206, &Hid::SendVibrationValues, "SendVibrationValues"},
- {207, &Hid::SendVibrationGcErmCommand, "SendVibrationGcErmCommand"},
- {208, &Hid::GetActualVibrationGcErmCommand, "GetActualVibrationGcErmCommand"},
- {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
- {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
- {211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
- {212, nullptr, "SendVibrationValueInBool"},
- {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
- {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
- {302, &Hid::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
- {303, &Hid::ActivateSevenSixAxisSensor, "ActivateSevenSixAxisSensor"},
- {304, &Hid::StartSevenSixAxisSensor, "StartSevenSixAxisSensor"},
- {305, &Hid::StopSevenSixAxisSensor, "StopSevenSixAxisSensor"},
- {306, &Hid::InitializeSevenSixAxisSensor, "InitializeSevenSixAxisSensor"},
- {307, &Hid::FinalizeSevenSixAxisSensor, "FinalizeSevenSixAxisSensor"},
- {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
- {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
- {310, &Hid::ResetSevenSixAxisSensorTimestamp, "ResetSevenSixAxisSensorTimestamp"},
- {400, &Hid::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
- {401, nullptr, "EnableUsbFullKeyController"},
- {402, nullptr, "IsUsbFullKeyControllerConnected"},
- {403, nullptr, "HasBattery"},
- {404, nullptr, "HasLeftRightBattery"},
- {405, nullptr, "GetNpadInterfaceType"},
- {406, nullptr, "GetNpadLeftRightInterfaceType"},
- {407, nullptr, "GetNpadOfHighestBatteryLevel"},
- {408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"},
- {500, &Hid::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"},
- {501, &Hid::InitializePalma, "InitializePalma"},
- {502, &Hid::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"},
- {503, &Hid::GetPalmaOperationInfo, "GetPalmaOperationInfo"},
- {504, &Hid::PlayPalmaActivity, "PlayPalmaActivity"},
- {505, &Hid::SetPalmaFrModeType, "SetPalmaFrModeType"},
- {506, &Hid::ReadPalmaStep, "ReadPalmaStep"},
- {507, &Hid::EnablePalmaStep, "EnablePalmaStep"},
- {508, &Hid::ResetPalmaStep, "ResetPalmaStep"},
- {509, &Hid::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"},
- {510, &Hid::WritePalmaApplicationSection, "WritePalmaApplicationSection"},
- {511, &Hid::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"},
- {512, &Hid::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"},
- {513, &Hid::WritePalmaActivityEntry, "WritePalmaActivityEntry"},
- {514, &Hid::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"},
- {515, &Hid::WritePalmaWaveEntry, "WritePalmaWaveEntry"},
- {516, &Hid::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"},
- {517, &Hid::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"},
- {518, &Hid::SuspendPalmaFeature, "SuspendPalmaFeature"},
- {519, &Hid::GetPalmaOperationResult, "GetPalmaOperationResult"},
- {520, &Hid::ReadPalmaPlayLog, "ReadPalmaPlayLog"},
- {521, &Hid::ResetPalmaPlayLog, "ResetPalmaPlayLog"},
- {522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
- {523, &Hid::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"},
- {524, &Hid::PairPalma, "PairPalma"},
- {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
- {526, &Hid::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"},
- {527, &Hid::EnablePalmaBoostMode, "EnablePalmaBoostMode"},
- {528, &Hid::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"},
- {529, &Hid::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"},
- {1000, &Hid::SetNpadCommunicationMode, "SetNpadCommunicationMode"},
- {1001, &Hid::GetNpadCommunicationMode, "GetNpadCommunicationMode"},
- {1002, &Hid::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"},
- {1003, &Hid::IsFirmwareUpdateNeededForNotification, "IsFirmwareUpdateNeededForNotification"},
- {2000, nullptr, "ActivateDigitizer"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
-}
-
-Hid::~Hid() = default;
-
-void Hid::CreateAppletResource(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- if (applet_resource == nullptr) {
- applet_resource = std::make_shared<IAppletResource>(system, service_context);
- }
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(ResultSuccess);
- rb.PushIpcInterface<IAppletResource>(applet_resource);
-}
-
-void Hid::ActivateDebugPad(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->ActivateController(HidController::DebugPad);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ActivateTouchScreen(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->ActivateController(HidController::Touchscreen);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ActivateMouse(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->ActivateController(HidController::Mouse);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ActivateKeyboard(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->ActivateController(HidController::Keyboard);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SendKeyboardLockKeyEvent(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto flags{rp.Pop<u32>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ActivateXpad(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- u32 basic_xpad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- applet_resource->ActivateController(HidController::XPad);
-
- LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
- parameters.basic_xpad_id, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetXpadIDs(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(0);
-}
-
-void Hid::ActivateSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- u32 basic_xpad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- // This function does nothing on 10.0.0+
-
- LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}",
- parameters.basic_xpad_id, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::DeactivateSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- u32 basic_xpad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- // This function does nothing on 10.0.0+
-
- LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}",
- parameters.basic_xpad_id, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::StartSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::StopSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- bool is_enabled{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(is_enabled);
-}
-
-void Hid::EnableSixAxisSensorFusion(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- bool enable_sixaxis_sensor_fusion;
- INSERT_PADDING_BYTES_NOINIT(3);
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle,
- parameters.enable_sixaxis_sensor_fusion);
-
- LOG_DEBUG(Service_HID,
- "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
- "device_index={}, applet_resource_user_id={}",
- parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type,
- parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
- parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- Core::HID::SixAxisSensorFusionParameters sixaxis_fusion;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
- "parameter2={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1,
- parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- Core::HID::SixAxisSensorFusionParameters fusion_parameters{};
- const auto& controller =
- GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(result);
- rb.PushRaw(fusion_parameters);
-}
-
-void Hid::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- // Since these parameters are unknown just use what HW outputs
- const Core::HID::SixAxisSensorFusionParameters fusion_parameters{
- .parameter1 = 0.03f,
- .parameter2 = 0.4f,
- };
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result1 =
- controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
- const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- if (result1.IsError()) {
- rb.Push(result1);
- return;
- }
- rb.Push(result2);
-}
-
-void Hid::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()};
- const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
- "applet_resource_user_id={}",
- sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index,
- drift_mode, applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.PushEnum(drift_mode);
-}
-
-void Hid::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::IsSixAxisSensorAtRest(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- bool is_at_rest{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(is_at_rest);
-}
-
-void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- bool is_firmware_available{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
- is_firmware_available);
-
- LOG_WARNING(
- Service_HID,
- "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(is_firmware_available);
-}
-
-void Hid::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- bool enabled;
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.EnableSixAxisSensorUnalteredPassthrough(
- parameters.sixaxis_handle, parameters.enabled);
-
- LOG_DEBUG(Service_HID,
- "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, "
- "applet_resource_user_id={}",
- parameters.enabled, parameters.sixaxis_handle.npad_type,
- parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
- parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- bool is_unaltered_sisxaxis_enabled{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.IsSixAxisSensorUnalteredPassthroughEnabled(
- parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled);
-
- LOG_DEBUG(
- Service_HID,
- "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(is_unaltered_sisxaxis_enabled);
-}
-
-void Hid::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- Core::HID::SixAxisSensorCalibrationParameter calibration{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration);
-
- LOG_WARNING(
- Service_HID,
- "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- if (result.IsSuccess()) {
- ctx.WriteBuffer(calibration);
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::GetSixAxisSensorIcInformation(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- Core::HID::SixAxisSensorIcInformation ic_information{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information);
-
- LOG_WARNING(
- Service_HID,
- "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- if (result.IsSuccess()) {
- ctx.WriteBuffer(ic_information);
- }
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::SixAxisSensorHandle sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
-
- LOG_WARNING(
- Service_HID,
- "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
- parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::ActivateGesture(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- u32 unknown;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- applet_resource->ActivateController(HidController::Gesture);
-
- LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
- parameters.unknown, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadStyleSet supported_styleset;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetSupportedStyleSet({parameters.supported_styleset});
-
- LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
- parameters.supported_styleset, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetSupportedStyleSet()
- .raw);
-}
-
-void Hid::SetSupportedNpadIdType(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- const auto result = applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetSupportedNpadIdTypes(ctx.ReadBuffer());
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::ActivateNpad(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->ActivateController(HidController::NPad);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::DeactivateNpad(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->DeactivateController(HidController::NPad);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- u64 unknown;
- };
- static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
- parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
-
- // Games expect this event to be signaled after calling this function
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SignalStyleSetChangedEvent(parameters.npad_id);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetStyleSetChangedEvent(parameters.npad_id));
-}
-
-void Hid::DisconnectNpad(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.DisconnectNpad(parameters.npad_id);
-
- LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
- parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetPlayerLedPattern(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
-
- Core::HID::LedPattern pattern{0, 0, 0, 0};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.GetLedPattern(npad_id, pattern);
-
- LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(result);
- rb.Push(pattern.raw);
-}
-
-void Hid::ActivateNpadWithRevision(HLERequestContext& ctx) {
- // Should have no effect with how our npad sets up the data
- IPC::RequestParser rp{ctx};
- struct Parameters {
- s32 revision;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- applet_resource->ActivateController(HidController::NPad);
-
- LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
- parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetNpadJoyHoldType(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
- applet_resource_user_id, hold_type);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetNpadJoyHoldType(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad).GetHoldType());
-}
-
-void Hid::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- Core::HID::NpadIdType new_npad_id{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(new_npad_id, parameters.npad_id,
- Controller_NPad::NpadJoyDeviceType::Left,
- Controller_NPad::NpadJoyAssignmentMode::Single);
-
- LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
- parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
- };
- static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- Core::HID::NpadIdType new_npad_id{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
- Controller_NPad::NpadJoyAssignmentMode::Single);
-
- LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
- parameters.npad_id, parameters.applet_resource_user_id,
- parameters.npad_joy_device_type);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- Core::HID::NpadIdType new_npad_id{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(new_npad_id, parameters.npad_id, {},
- Controller_NPad::NpadJoyAssignmentMode::Dual);
-
- LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
- parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
- const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
-
- LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
- npad_id_1, npad_id_2, applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::StartLrAssignmentMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad).StartLRAssignmentMode();
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::StopLrAssignmentMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad).StopLRAssignmentMode();
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadHandheldActivationMode(activation_mode);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
- applet_resource_user_id, activation_mode);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetNpadHandheldActivationMode());
-}
-
-void Hid::SwapNpadAssignment(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
- const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SwapNpadAssignment(npad_id_1, npad_id_2);
-
- LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
- npad_id_1, npad_id_2, applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- bool is_enabled = false;
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result =
- controller.IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
-
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
- parameters.npad_id, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(is_enabled);
-}
-
-void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- bool unintended_home_button_input_protection;
- INSERT_PADDING_BYTES_NOINIT(3);
- Core::HID::NpadIdType npad_id;
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled(
- parameters.unintended_home_button_input_protection, parameters.npad_id);
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, unintended_home_button_input_protection={}, npad_id={},"
- "applet_resource_user_id={}",
- parameters.unintended_home_button_input_protection, parameters.npad_id,
- parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
- };
- static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- Core::HID::NpadIdType new_npad_id{};
- auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- const auto is_reassigned =
- controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
- Controller_NPad::NpadJoyAssignmentMode::Single);
-
- LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
- parameters.npad_id, parameters.applet_resource_user_id,
- parameters.npad_joy_device_type);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.Push(is_reassigned);
- rb.PushEnum(new_npad_id);
-}
-
-void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- bool analog_stick_use_center_clamp;
- INSERT_PADDING_BYTES_NOINIT(7);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- GetAppletResource()
- ->GetController<Controller_NPad>(HidController::NPad)
- .SetAnalogStickUseCenterClamp(parameters.analog_stick_use_center_clamp);
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
- parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadStyleSet npad_styleset;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- Core::HID::NpadButton button;
- };
- static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}",
- parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
- applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetVibrationDeviceInfo(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
- const auto& controller =
- GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
-
- Core::HID::VibrationDeviceInfo vibration_device_info;
- bool check_device_index = false;
-
- switch (vibration_device_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Handheld:
- case Core::HID::NpadStyleIndex::JoyconDual:
- case Core::HID::NpadStyleIndex::JoyconLeft:
- case Core::HID::NpadStyleIndex::JoyconRight:
- vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator;
- check_device_index = true;
- break;
- case Core::HID::NpadStyleIndex::GameCube:
- vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm;
- break;
- case Core::HID::NpadStyleIndex::N64:
- vibration_device_info.type = Core::HID::VibrationDeviceType::N64;
- break;
- default:
- vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown;
- break;
- }
-
- vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
- if (check_device_index) {
- switch (vibration_device_handle.device_index) {
- case Core::HID::DeviceIndex::Left:
- vibration_device_info.position = Core::HID::VibrationDevicePosition::Left;
- break;
- case Core::HID::DeviceIndex::Right:
- vibration_device_info.position = Core::HID::VibrationDevicePosition::Right;
- break;
- case Core::HID::DeviceIndex::None:
- default:
- ASSERT_MSG(false, "DeviceIndex should never be None!");
- break;
- }
- }
-
- LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
- vibration_device_info.type, vibration_device_info.position);
-
- const auto result = controller.IsDeviceHandleValid(vibration_device_handle);
- if (result.IsError()) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushRaw(vibration_device_info);
-}
-
-void Hid::SendVibrationValue(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::VibrationDeviceHandle vibration_device_handle;
- Core::HID::VibrationValue vibration_value;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .VibrateController(parameters.vibration_device_handle, parameters.vibration_value);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.vibration_device_handle.npad_type,
- parameters.vibration_device_handle.npad_id,
- parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetActualVibrationValue(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::VibrationDeviceHandle vibration_device_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.vibration_device_handle.npad_type,
- parameters.vibration_device_handle.npad_id,
- parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 6};
- rb.Push(ResultSuccess);
- rb.PushRaw(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetLastVibration(parameters.vibration_device_handle));
-}
-
-void Hid::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
- LOG_DEBUG(Service_HID, "called");
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(ResultSuccess);
- rb.PushIpcInterface<IActiveVibrationDeviceList>(system, applet_resource);
-}
-
-void Hid::PermitVibration(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto can_vibrate{rp.Pop<bool>()};
-
- // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value
- // by converting it to a bool
- Settings::values.vibration_enabled.SetValue(can_vibrate);
-
- LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::IsVibrationPermitted(HLERequestContext& ctx) {
- LOG_DEBUG(Service_HID, "called");
-
- // nnSDK checks if a float is greater than zero. We return the bool we stored earlier
- const auto is_enabled = Settings::values.vibration_enabled.GetValue();
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(is_enabled);
-}
-
-void Hid::SendVibrationValues(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- const auto handle_data = ctx.ReadBuffer(0);
- const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0);
- const auto vibration_data = ctx.ReadBuffer(1);
- const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1);
-
- auto vibration_device_handles =
- std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()),
- handle_count);
- auto vibration_values = std::span(
- reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .VibrateControllers(vibration_device_handles, vibration_values);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SendVibrationGcErmCommand(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::VibrationDeviceHandle vibration_device_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- Core::HID::VibrationGcErmCommand gc_erm_command;
- };
- static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- /**
- * Note: This uses yuzu-specific behavior such that the StopHard command produces
- * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below,
- * in order to differentiate between Stop and StopHard commands.
- * This is done to reuse the controller vibration functions made for regular controllers.
- */
- const auto vibration_value = [parameters] {
- switch (parameters.gc_erm_command) {
- case Core::HID::VibrationGcErmCommand::Stop:
- return Core::HID::VibrationValue{
- .low_amplitude = 0.0f,
- .low_frequency = 160.0f,
- .high_amplitude = 0.0f,
- .high_frequency = 320.0f,
- };
- case Core::HID::VibrationGcErmCommand::Start:
- return Core::HID::VibrationValue{
- .low_amplitude = 1.0f,
- .low_frequency = 160.0f,
- .high_amplitude = 1.0f,
- .high_frequency = 320.0f,
- };
- case Core::HID::VibrationGcErmCommand::StopHard:
- return Core::HID::VibrationValue{
- .low_amplitude = 0.0f,
- .low_frequency = 0.0f,
- .high_amplitude = 0.0f,
- .high_frequency = 0.0f,
- };
- default:
- return Core::HID::DEFAULT_VIBRATION_VALUE;
- }
- }();
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .VibrateController(parameters.vibration_device_handle, vibration_value);
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
- "gc_erm_command={}",
- parameters.vibration_device_handle.npad_type,
- parameters.vibration_device_handle.npad_id,
- parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id,
- parameters.gc_erm_command);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::VibrationDeviceHandle vibration_device_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- const auto last_vibration = applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetLastVibration(parameters.vibration_device_handle);
-
- const auto gc_erm_command = [last_vibration] {
- if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
- return Core::HID::VibrationGcErmCommand::Start;
- }
-
- /**
- * Note: This uses yuzu-specific behavior such that the StopHard command produces
- * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function
- * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands.
- * This is done to reuse the controller vibration functions made for regular controllers.
- */
- if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) {
- return Core::HID::VibrationGcErmCommand::StopHard;
- }
-
- return Core::HID::VibrationGcErmCommand::Stop;
- }();
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.vibration_device_handle.npad_type,
- parameters.vibration_device_handle.npad_id,
- parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(gc_erm_command);
-}
-
-void Hid::BeginPermitVibrationSession(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetPermitVibrationSession(true);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::EndPermitVibrationSession(HLERequestContext& ctx) {
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetPermitVibrationSession(false);
-
- LOG_DEBUG(Service_HID, "called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::IsVibrationDeviceMounted(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::VibrationDeviceHandle vibration_device_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_DEBUG(Service_HID,
- "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
- parameters.vibration_device_handle.npad_type,
- parameters.vibration_device_handle.npad_id,
- parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .IsVibrationDeviceMounted(parameters.vibration_device_handle));
-}
-
-void Hid::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->ActivateController(HidController::ConsoleSixAxisSensor);
-
- LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::StartConsoleSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
- parameters.console_sixaxis_handle.unknown_1,
- parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::StopConsoleSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
- parameters.console_sixaxis_handle.unknown_1,
- parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ActivateSevenSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->ActivateController(HidController::ConsoleSixAxisSensor);
-
- LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::StartSevenSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
- applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::StopSevenSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
- applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto t_mem_1_size{rp.Pop<u64>()};
- const auto t_mem_2_size{rp.Pop<u64>()};
- const auto t_mem_1_handle{ctx.GetCopyHandle(0)};
- const auto t_mem_2_handle{ctx.GetCopyHandle(1)};
-
- ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes");
- ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
-
- auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_1_handle);
-
- if (t_mem_1.IsNull()) {
- LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultUnknown);
- return;
- }
-
- auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_2_handle);
-
- if (t_mem_2.IsNull()) {
- LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultUnknown);
- return;
- }
-
- ASSERT_MSG(t_mem_1->GetSize() == 0x1000, "t_mem_1 has incorrect size");
- ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size");
-
- // Activate console six axis controller
- applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
- .ActivateController();
-
- applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
- .SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
-
- LOG_WARNING(Service_HID,
- "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
- "applet_resource_user_id={}",
- t_mem_1_handle, t_mem_2_handle, applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::FinalizeSevenSixAxisSensor(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
- applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
- .ResetTimestamp();
-
- LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
-
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(false);
-}
-
-void Hid::GetPalmaConnectionHandle(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
- parameters.npad_id, parameters.applet_resource_user_id);
-
- Controller_Palma::PalmaConnectionHandle handle;
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle);
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(result);
- rb.PushRaw(handle);
-}
-
-void Hid::InitializePalma(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result = controller.InitializePalma(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle));
-}
-
-void Hid::GetPalmaOperationInfo(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- Controller_Palma::PalmaOperationType operation_type;
- Controller_Palma::PalmaOperationData data;
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data);
-
- if (result.IsError()) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- }
-
- ctx.WriteBuffer(data);
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(result);
- rb.Push(static_cast<u64>(operation_type));
-}
-
-void Hid::PlayPalmaActivity(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
- const auto palma_activity{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}",
- connection_handle.npad_id, palma_activity);
-
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::SetPalmaFrModeType(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
- const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}",
- connection_handle.npad_id, fr_mode);
-
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::ReadPalmaStep(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result = controller.ReadPalmaStep(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::EnablePalmaStep(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- bool is_enabled;
- INSERT_PADDING_WORDS_NOINIT(1);
- Controller_Palma::PalmaConnectionHandle connection_handle;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}",
- parameters.connection_handle.npad_id, parameters.is_enabled);
-
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result =
- controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::ResetPalmaStep(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
- const auto result = controller.ResetPalmaStep(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::ReadPalmaApplicationSection(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::WritePalmaApplicationSection(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ReadPalmaUniqueCode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .ReadPalmaUniqueCode(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .SetPalmaUniqueCodeInvalid(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::WritePalmaActivityEntry(HLERequestContext& ctx) {
- LOG_CRITICAL(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
- const auto unknown{rp.Pop<u64>()};
-
- [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
- connection_handle.npad_id, unknown);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .WritePalmaRgbLedPatternEntry(connection_handle, unknown);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::WritePalmaWaveEntry(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
- const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()};
- const auto unknown{rp.Pop<u64>()};
- const auto t_mem_size{rp.Pop<u64>()};
- const auto t_mem_handle{ctx.GetCopyHandle(0)};
- const auto size{rp.Pop<u64>()};
-
- ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
-
- auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
- t_mem_handle);
-
- if (t_mem.IsNull()) {
- LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultUnknown);
- return;
- }
-
- ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
- "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
- connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .WritePalmaWaveEntry(connection_handle, wave_set, t_mem->GetSourceAddress(), t_mem_size);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- s32 database_id_version;
- INSERT_PADDING_WORDS_NOINIT(1);
- Controller_Palma::PalmaConnectionHandle connection_handle;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}",
- parameters.connection_handle.npad_id, parameters.database_id_version);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .SetPalmaDataBaseIdentificationVersion(parameters.connection_handle,
- parameters.database_id_version);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .GetPalmaDataBaseIdentificationVersion(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SuspendPalmaFeature(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetPalmaOperationResult(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- const auto result = applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .GetPalmaOperationResult(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
-}
-
-void Hid::ReadPalmaPlayLog(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::ResetPalmaPlayLog(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetIsPalmaAllConnectable(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- bool is_palma_all_connectable;
- INSERT_PADDING_BYTES_NOINIT(7);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}",
- parameters.is_palma_all_connectable, parameters.applet_resource_user_id);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetIsPalmaPairedConnectable(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::PairPalma(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .PairPalma(connection_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetPalmaBoostMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto palma_boost_mode{rp.Pop<bool>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode);
-
- applet_resource->GetController<Controller_Palma>(HidController::Palma)
- .SetPalmaBoostMode(palma_boost_mode);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::CancelWritePalmaWaveEntry(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::EnablePalmaBoostMode(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetPalmaBluetoothAddress(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetDisallowedPalmaConnection(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::SetNpadCommunicationMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()};
-
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadCommunicationMode(communication_mode);
-
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
- applet_resource_user_id, communication_mode);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::GetNpadCommunicationMode(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
-
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetNpadCommunicationMode());
-}
-
-void Hid::SetTouchScreenConfiguration(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto touchscreen_mode{rp.PopRaw<Core::HID::TouchScreenConfigurationForNx>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, touchscreen_mode={}, applet_resource_user_id={}",
- touchscreen_mode.mode, applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void Hid::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- s32 unknown;
- INSERT_PADDING_WORDS_NOINIT(1);
- u64 applet_resource_user_id;
- };
- static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
- parameters.unknown, parameters.applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(false);
-}
-
-class HidDbg final : public ServiceFramework<HidDbg> {
-public:
- explicit HidDbg(Core::System& system_) : ServiceFramework{system_, "hid:dbg"} {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, nullptr, "DeactivateDebugPad"},
- {1, nullptr, "SetDebugPadAutoPilotState"},
- {2, nullptr, "UnsetDebugPadAutoPilotState"},
- {10, nullptr, "DeactivateTouchScreen"},
- {11, nullptr, "SetTouchScreenAutoPilotState"},
- {12, nullptr, "UnsetTouchScreenAutoPilotState"},
- {13, nullptr, "GetTouchScreenConfiguration"},
- {14, nullptr, "ProcessTouchScreenAutoTune"},
- {15, nullptr, "ForceStopTouchScreenManagement"},
- {16, nullptr, "ForceRestartTouchScreenManagement"},
- {17, nullptr, "IsTouchScreenManaged"},
- {20, nullptr, "DeactivateMouse"},
- {21, nullptr, "SetMouseAutoPilotState"},
- {22, nullptr, "UnsetMouseAutoPilotState"},
- {25, nullptr, "SetDebugMouseAutoPilotState"},
- {26, nullptr, "UnsetDebugMouseAutoPilotState"},
- {30, nullptr, "DeactivateKeyboard"},
- {31, nullptr, "SetKeyboardAutoPilotState"},
- {32, nullptr, "UnsetKeyboardAutoPilotState"},
- {50, nullptr, "DeactivateXpad"},
- {51, nullptr, "SetXpadAutoPilotState"},
- {52, nullptr, "UnsetXpadAutoPilotState"},
- {53, nullptr, "DeactivateJoyXpad"},
- {60, nullptr, "ClearNpadSystemCommonPolicy"},
- {61, nullptr, "DeactivateNpad"},
- {62, nullptr, "ForceDisconnectNpad"},
- {91, nullptr, "DeactivateGesture"},
- {110, nullptr, "DeactivateHomeButton"},
- {111, nullptr, "SetHomeButtonAutoPilotState"},
- {112, nullptr, "UnsetHomeButtonAutoPilotState"},
- {120, nullptr, "DeactivateSleepButton"},
- {121, nullptr, "SetSleepButtonAutoPilotState"},
- {122, nullptr, "UnsetSleepButtonAutoPilotState"},
- {123, nullptr, "DeactivateInputDetector"},
- {130, nullptr, "DeactivateCaptureButton"},
- {131, nullptr, "SetCaptureButtonAutoPilotState"},
- {132, nullptr, "UnsetCaptureButtonAutoPilotState"},
- {133, nullptr, "SetShiftAccelerometerCalibrationValue"},
- {134, nullptr, "GetShiftAccelerometerCalibrationValue"},
- {135, nullptr, "SetShiftGyroscopeCalibrationValue"},
- {136, nullptr, "GetShiftGyroscopeCalibrationValue"},
- {140, nullptr, "DeactivateConsoleSixAxisSensor"},
- {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
- {142, nullptr, "DeactivateSevenSixAxisSensor"},
- {143, nullptr, "GetConsoleSixAxisSensorCountStates"},
- {144, nullptr, "GetAccelerometerFsr"},
- {145, nullptr, "SetAccelerometerFsr"},
- {146, nullptr, "GetAccelerometerOdr"},
- {147, nullptr, "SetAccelerometerOdr"},
- {148, nullptr, "GetGyroscopeFsr"},
- {149, nullptr, "SetGyroscopeFsr"},
- {150, nullptr, "GetGyroscopeOdr"},
- {151, nullptr, "SetGyroscopeOdr"},
- {152, nullptr, "GetWhoAmI"},
- {201, nullptr, "ActivateFirmwareUpdate"},
- {202, nullptr, "DeactivateFirmwareUpdate"},
- {203, nullptr, "StartFirmwareUpdate"},
- {204, nullptr, "GetFirmwareUpdateStage"},
- {205, nullptr, "GetFirmwareVersion"},
- {206, nullptr, "GetDestinationFirmwareVersion"},
- {207, nullptr, "DiscardFirmwareInfoCacheForRevert"},
- {208, nullptr, "StartFirmwareUpdateForRevert"},
- {209, nullptr, "GetAvailableFirmwareVersionForRevert"},
- {210, nullptr, "IsFirmwareUpdatingDevice"},
- {211, nullptr, "StartFirmwareUpdateIndividual"},
- {215, nullptr, "SetUsbFirmwareForceUpdateEnabled"},
- {216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"},
- {221, nullptr, "UpdateControllerColor"},
- {222, nullptr, "ConnectUsbPadsAsync"},
- {223, nullptr, "DisconnectUsbPadsAsync"},
- {224, nullptr, "UpdateDesignInfo"},
- {225, nullptr, "GetUniquePadDriverState"},
- {226, nullptr, "GetSixAxisSensorDriverStates"},
- {227, nullptr, "GetRxPacketHistory"},
- {228, nullptr, "AcquireOperationEventHandle"},
- {229, nullptr, "ReadSerialFlash"},
- {230, nullptr, "WriteSerialFlash"},
- {231, nullptr, "GetOperationResult"},
- {232, nullptr, "EnableShipmentMode"},
- {233, nullptr, "ClearPairingInfo"},
- {234, nullptr, "GetUniquePadDeviceTypeSetInternal"},
- {235, nullptr, "EnableAnalogStickPower"},
- {236, nullptr, "RequestKuinaUartClockCal"},
- {237, nullptr, "GetKuinaUartClockCal"},
- {238, nullptr, "SetKuinaUartClockTrim"},
- {239, nullptr, "KuinaLoopbackTest"},
- {240, nullptr, "RequestBatteryVoltage"},
- {241, nullptr, "GetBatteryVoltage"},
- {242, nullptr, "GetUniquePadPowerInfo"},
- {243, nullptr, "RebootUniquePad"},
- {244, nullptr, "RequestKuinaFirmwareVersion"},
- {245, nullptr, "GetKuinaFirmwareVersion"},
- {246, nullptr, "GetVidPid"},
- {247, nullptr, "GetAnalogStickCalibrationValue"},
- {248, nullptr, "GetUniquePadIdsFull"},
- {249, nullptr, "ConnectUniquePad"},
- {250, nullptr, "IsVirtual"},
- {251, nullptr, "GetAnalogStickModuleParam"},
- {301, nullptr, "GetAbstractedPadHandles"},
- {302, nullptr, "GetAbstractedPadState"},
- {303, nullptr, "GetAbstractedPadsState"},
- {321, nullptr, "SetAutoPilotVirtualPadState"},
- {322, nullptr, "UnsetAutoPilotVirtualPadState"},
- {323, nullptr, "UnsetAllAutoPilotVirtualPadState"},
- {324, nullptr, "AttachHdlsWorkBuffer"},
- {325, nullptr, "ReleaseHdlsWorkBuffer"},
- {326, nullptr, "DumpHdlsNpadAssignmentState"},
- {327, nullptr, "DumpHdlsStates"},
- {328, nullptr, "ApplyHdlsNpadAssignmentState"},
- {329, nullptr, "ApplyHdlsStateList"},
- {330, nullptr, "AttachHdlsVirtualDevice"},
- {331, nullptr, "DetachHdlsVirtualDevice"},
- {332, nullptr, "SetHdlsState"},
- {350, nullptr, "AddRegisteredDevice"},
- {400, nullptr, "DisableExternalMcuOnNxDevice"},
- {401, nullptr, "DisableRailDeviceFiltering"},
- {402, nullptr, "EnableWiredPairing"},
- {403, nullptr, "EnableShipmentModeAutoClear"},
- {404, nullptr, "SetRailEnabled"},
- {500, nullptr, "SetFactoryInt"},
- {501, nullptr, "IsFactoryBootEnabled"},
- {550, nullptr, "SetAnalogStickModelDataTemporarily"},
- {551, nullptr, "GetAnalogStickModelData"},
- {552, nullptr, "ResetAnalogStickModelData"},
- {600, nullptr, "ConvertPadState"},
- {650, nullptr, "AddButtonPlayData"},
- {651, nullptr, "StartButtonPlayData"},
- {652, nullptr, "StopButtonPlayData"},
- {2000, nullptr, "DeactivateDigitizer"},
- {2001, nullptr, "SetDigitizerAutoPilotState"},
- {2002, nullptr, "UnsetDigitizerAutoPilotState"},
- {2002, nullptr, "ReloadFirmwareDebugSettings"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
- }
-};
-
-class HidSys final : public ServiceFramework<HidSys> {
-public:
- explicit HidSys(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_)
- : ServiceFramework{system_, "hid:sys"}, service_context{system_, "hid:sys"},
- applet_resource{applet_resource_} {
- // clang-format off
- static const FunctionInfo functions[] = {
- {31, nullptr, "SendKeyboardLockKeyEvent"},
- {101, nullptr, "AcquireHomeButtonEventHandle"},
- {111, nullptr, "ActivateHomeButton"},
- {121, nullptr, "AcquireSleepButtonEventHandle"},
- {131, nullptr, "ActivateSleepButton"},
- {141, nullptr, "AcquireCaptureButtonEventHandle"},
- {151, nullptr, "ActivateCaptureButton"},
- {161, nullptr, "GetPlatformConfig"},
- {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
- {211, nullptr, "GetNpadsWithNfc"},
- {212, nullptr, "AcquireNfcActivateEventHandle"},
- {213, nullptr, "ActivateNfc"},
- {214, nullptr, "GetXcdHandleForNpadWithNfc"},
- {215, nullptr, "IsNfcActivated"},
- {230, nullptr, "AcquireIrSensorEventHandle"},
- {231, nullptr, "ActivateIrSensor"},
- {232, nullptr, "GetIrSensorState"},
- {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
- {301, nullptr, "ActivateNpadSystem"},
- {303, &HidSys::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
- {304, nullptr, "EnableAssigningSingleOnSlSrPress"},
- {305, nullptr, "DisableAssigningSingleOnSlSrPress"},
- {306, &HidSys::GetLastActiveNpad, "GetLastActiveNpad"},
- {307, nullptr, "GetNpadSystemExtStyle"},
- {308, nullptr, "ApplyNpadSystemCommonPolicyFull"},
- {309, nullptr, "GetNpadFullKeyGripColor"},
- {310, nullptr, "GetMaskedSupportedNpadStyleSet"},
- {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
- {312, nullptr, "SetSupportedNpadStyleSetAll"},
- {313, nullptr, "GetNpadCaptureButtonAssignment"},
- {314, nullptr, "GetAppletFooterUiType"},
- {315, nullptr, "GetAppletDetailedUiType"},
- {316, nullptr, "GetNpadInterfaceType"},
- {317, nullptr, "GetNpadLeftRightInterfaceType"},
- {318, nullptr, "HasBattery"},
- {319, nullptr, "HasLeftRightBattery"},
- {321, &HidSys::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
- {322, nullptr, "GetIrSensorState"},
- {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
- {324, nullptr, "GetUniquePadButtonSet"},
- {325, nullptr, "GetUniquePadColor"},
- {326, nullptr, "GetUniquePadAppletDetailedUiType"},
- {327, nullptr, "GetAbstractedPadIdDataFromNpad"},
- {328, nullptr, "AttachAbstractedPadToNpad"},
- {329, nullptr, "DetachAbstractedPadAll"},
- {330, nullptr, "CheckAbstractedPadConnection"},
- {500, nullptr, "SetAppletResourceUserId"},
- {501, nullptr, "RegisterAppletResourceUserId"},
- {502, nullptr, "UnregisterAppletResourceUserId"},
- {503, nullptr, "EnableAppletToGetInput"},
- {504, nullptr, "SetAruidValidForVibration"},
- {505, nullptr, "EnableAppletToGetSixAxisSensor"},
- {506, nullptr, "EnableAppletToGetPadInput"},
- {507, nullptr, "EnableAppletToGetTouchScreen"},
- {510, nullptr, "SetVibrationMasterVolume"},
- {511, nullptr, "GetVibrationMasterVolume"},
- {512, nullptr, "BeginPermitVibrationSession"},
- {513, nullptr, "EndPermitVibrationSession"},
- {514, nullptr, "Unknown514"},
- {520, nullptr, "EnableHandheldHids"},
- {521, nullptr, "DisableHandheldHids"},
- {522, nullptr, "SetJoyConRailEnabled"},
- {523, nullptr, "IsJoyConRailEnabled"},
- {524, nullptr, "IsHandheldHidsEnabled"},
- {525, nullptr, "IsJoyConAttachedOnAllRail"},
- {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
- {541, nullptr, "GetPlayReportControllerUsages"},
- {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
- {543, nullptr, "GetRegisteredDevicesOld"},
- {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"},
- {545, nullptr, "SendConnectionTrigger"},
- {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"},
- {547, nullptr, "GetAllowedBluetoothLinksCount"},
- {548, nullptr, "GetRegisteredDevices"},
- {549, nullptr, "GetConnectableRegisteredDevices"},
- {700, nullptr, "ActivateUniquePad"},
- {702, nullptr, "AcquireUniquePadConnectionEventHandle"},
- {703, nullptr, "GetUniquePadIds"},
- {751, &HidSys::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
- {800, nullptr, "ListSixAxisSensorHandles"},
- {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
- {802, nullptr, "ResetSixAxisSensorCalibrationValues"},
- {803, nullptr, "StartSixAxisSensorUserCalibration"},
- {804, nullptr, "CancelSixAxisSensorUserCalibration"},
- {805, nullptr, "GetUniquePadBluetoothAddress"},
- {806, nullptr, "DisconnectUniquePad"},
- {807, nullptr, "GetUniquePadType"},
- {808, nullptr, "GetUniquePadInterface"},
- {809, nullptr, "GetUniquePadSerialNumber"},
- {810, nullptr, "GetUniquePadControllerNumber"},
- {811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
- {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
- {821, nullptr, "StartAnalogStickManualCalibration"},
- {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
- {823, nullptr, "CancelAnalogStickManualCalibration"},
- {824, nullptr, "ResetAnalogStickManualCalibration"},
- {825, nullptr, "GetAnalogStickState"},
- {826, nullptr, "GetAnalogStickManualCalibrationStage"},
- {827, nullptr, "IsAnalogStickButtonPressed"},
- {828, nullptr, "IsAnalogStickInReleasePosition"},
- {829, nullptr, "IsAnalogStickInCircumference"},
- {830, nullptr, "SetNotificationLedPattern"},
- {831, nullptr, "SetNotificationLedPatternWithTimeout"},
- {832, nullptr, "PrepareHidsForNotificationWake"},
- {850, &HidSys::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
- {851, nullptr, "EnableUsbFullKeyController"},
- {852, nullptr, "IsUsbConnected"},
- {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"},
- {900, nullptr, "ActivateInputDetector"},
- {901, nullptr, "NotifyInputDetector"},
- {1000, nullptr, "InitializeFirmwareUpdate"},
- {1001, nullptr, "GetFirmwareVersion"},
- {1002, nullptr, "GetAvailableFirmwareVersion"},
- {1003, nullptr, "IsFirmwareUpdateAvailable"},
- {1004, nullptr, "CheckFirmwareUpdateRequired"},
- {1005, nullptr, "StartFirmwareUpdate"},
- {1006, nullptr, "AbortFirmwareUpdate"},
- {1007, nullptr, "GetFirmwareUpdateState"},
- {1008, nullptr, "ActivateAudioControl"},
- {1009, nullptr, "AcquireAudioControlEventHandle"},
- {1010, nullptr, "GetAudioControlStates"},
- {1011, nullptr, "DeactivateAudioControl"},
- {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
- {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
- {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
- {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
- {1100, nullptr, "GetHidbusSystemServiceObject"},
- {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
- {1130, nullptr, "InitializeUsbFirmwareUpdate"},
- {1131, nullptr, "FinalizeUsbFirmwareUpdate"},
- {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
- {1133, nullptr, "StartUsbFirmwareUpdate"},
- {1134, nullptr, "GetUsbFirmwareUpdateState"},
- {1150, nullptr, "SetTouchScreenMagnification"},
- {1151, nullptr, "GetTouchScreenFirmwareVersion"},
- {1152, nullptr, "SetTouchScreenDefaultConfiguration"},
- {1153, &HidSys::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"},
- {1154, nullptr, "IsFirmwareAvailableForNotification"},
- {1155, nullptr, "SetForceHandheldStyleVibration"},
- {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
- {1157, nullptr, "CancelConnectionTrigger"},
- {1200, nullptr, "IsButtonConfigSupported"},
- {1201, nullptr, "IsButtonConfigEmbeddedSupported"},
- {1202, nullptr, "DeleteButtonConfig"},
- {1203, nullptr, "DeleteButtonConfigEmbedded"},
- {1204, nullptr, "SetButtonConfigEnabled"},
- {1205, nullptr, "SetButtonConfigEmbeddedEnabled"},
- {1206, nullptr, "IsButtonConfigEnabled"},
- {1207, nullptr, "IsButtonConfigEmbeddedEnabled"},
- {1208, nullptr, "SetButtonConfigEmbedded"},
- {1209, nullptr, "SetButtonConfigFull"},
- {1210, nullptr, "SetButtonConfigLeft"},
- {1211, nullptr, "SetButtonConfigRight"},
- {1212, nullptr, "GetButtonConfigEmbedded"},
- {1213, nullptr, "GetButtonConfigFull"},
- {1214, nullptr, "GetButtonConfigLeft"},
- {1215, nullptr, "GetButtonConfigRight"},
- {1250, nullptr, "IsCustomButtonConfigSupported"},
- {1251, nullptr, "IsDefaultButtonConfigEmbedded"},
- {1252, nullptr, "IsDefaultButtonConfigFull"},
- {1253, nullptr, "IsDefaultButtonConfigLeft"},
- {1254, nullptr, "IsDefaultButtonConfigRight"},
- {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"},
- {1256, nullptr, "IsButtonConfigStorageFullEmpty"},
- {1257, nullptr, "IsButtonConfigStorageLeftEmpty"},
- {1258, nullptr, "IsButtonConfigStorageRightEmpty"},
- {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"},
- {1260, nullptr, "GetButtonConfigStorageFullDeprecated"},
- {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"},
- {1262, nullptr, "GetButtonConfigStorageRightDeprecated"},
- {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"},
- {1264, nullptr, "SetButtonConfigStorageFullDeprecated"},
- {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"},
- {1266, nullptr, "SetButtonConfigStorageRightDeprecated"},
- {1267, nullptr, "DeleteButtonConfigStorageEmbedded"},
- {1268, nullptr, "DeleteButtonConfigStorageFull"},
- {1269, nullptr, "DeleteButtonConfigStorageLeft"},
- {1270, nullptr, "DeleteButtonConfigStorageRight"},
- {1271, nullptr, "IsUsingCustomButtonConfig"},
- {1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
- {1273, nullptr, "SetAllCustomButtonConfigEnabled"},
- {1274, nullptr, "SetDefaultButtonConfig"},
- {1275, nullptr, "SetAllDefaultButtonConfig"},
- {1276, nullptr, "SetHidButtonConfigEmbedded"},
- {1277, nullptr, "SetHidButtonConfigFull"},
- {1278, nullptr, "SetHidButtonConfigLeft"},
- {1279, nullptr, "SetHidButtonConfigRight"},
- {1280, nullptr, "GetHidButtonConfigEmbedded"},
- {1281, nullptr, "GetHidButtonConfigFull"},
- {1282, nullptr, "GetHidButtonConfigLeft"},
- {1283, nullptr, "GetHidButtonConfigRight"},
- {1284, nullptr, "GetButtonConfigStorageEmbedded"},
- {1285, nullptr, "GetButtonConfigStorageFull"},
- {1286, nullptr, "GetButtonConfigStorageLeft"},
- {1287, nullptr, "GetButtonConfigStorageRight"},
- {1288, nullptr, "SetButtonConfigStorageEmbedded"},
- {1289, nullptr, "SetButtonConfigStorageFull"},
- {1290, nullptr, "DeleteButtonConfigStorageRight"},
- {1291, nullptr, "DeleteButtonConfigStorageRight"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
-
- joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent");
- }
-
- ~HidSys() {
- service_context.CloseEvent(joy_detach_event);
- };
-
-private:
- void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "called");
-
- GetAppletResource()
- ->GetController<Controller_NPad>(HidController::NPad)
- .ApplyNpadSystemCommonPolicy();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
- }
-
- void GetLastActiveNpad(HLERequestContext& ctx) {
- LOG_DEBUG(Service_HID, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.PushEnum(system.HIDCore().GetLastActiveController());
- }
-
- void GetUniquePadsFromNpad(HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type);
-
- const std::vector<Core::HID::UniquePadId> unique_pads{};
-
- ctx.WriteBuffer(unique_pads);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(static_cast<u32>(unique_pads.size()));
- }
-
- void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) {
- LOG_INFO(Service_AM, "called");
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(joy_detach_event->GetReadableEvent());
- }
-
- void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
- const bool is_enabled = false;
-
- LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(is_enabled);
- }
-
- void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
-
- Core::HID::TouchScreenConfigurationForNx touchscreen_config{
- .mode = Core::HID::TouchScreenModeForNx::Finger,
- };
-
- if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 &&
- touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) {
- touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting;
- }
-
- IPC::ResponseBuilder rb{ctx, 6};
- rb.Push(ResultSuccess);
- rb.PushRaw(touchscreen_config);
- }
-
- std::shared_ptr<IAppletResource> GetAppletResource() {
- if (applet_resource == nullptr) {
- applet_resource = std::make_shared<IAppletResource>(system, service_context);
- }
-
- return applet_resource;
- }
-
- Kernel::KEvent* joy_detach_event;
- KernelHelpers::ServiceContext service_context;
- std::shared_ptr<IAppletResource> applet_resource;
-};
-
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- std::shared_ptr<IAppletResource> applet_resource;
+ std::shared_ptr<ResourceManager> resouce_manager = std::make_shared<ResourceManager>(system);
+ std::shared_ptr<HidFirmwareSettings> firmware_settings =
+ std::make_shared<HidFirmwareSettings>();
+
+ server_manager->RegisterNamedService(
+ "hid", std::make_shared<IHidServer>(system, resouce_manager, firmware_settings));
+ server_manager->RegisterNamedService(
+ "hid:dbg", std::make_shared<IHidDebugServer>(system, resouce_manager));
+ server_manager->RegisterNamedService(
+ "hid:sys", std::make_shared<IHidSystemServer>(system, resouce_manager));
- server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system, applet_resource));
server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system));
- server_manager->RegisterNamedService("hid:dbg", std::make_shared<HidDbg>(system));
- server_manager->RegisterNamedService("hid:sys",
- std::make_shared<HidSys>(system, applet_resource));
- server_manager->RegisterNamedService("irs", std::make_shared<Service::IRS::IRS>(system));
- server_manager->RegisterNamedService("irs:sys",
- std::make_shared<Service::IRS::IRS_SYS>(system));
+ server_manager->RegisterNamedService("irs", std::make_shared<IRS::IRS>(system));
+ server_manager->RegisterNamedService("irs:sys", std::make_shared<IRS::IRS_SYS>(system));
server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system));
+
system.RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 0ca43de93..ec5463f4e 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -3,220 +3,12 @@
#pragma once
-#include <chrono>
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Core::Timing {
-struct EventType;
-}
-
-namespace Service::SM {
-class ServiceManager;
+namespace Core {
+class System;
}
namespace Service::HID {
-enum class HidController : std::size_t {
- DebugPad,
- Touchscreen,
- Mouse,
- Keyboard,
- XPad,
- HomeButton,
- SleepButton,
- CaptureButton,
- InputDetector,
- UniquePad,
- NPad,
- Gesture,
- ConsoleSixAxisSensor,
- DebugMouse,
- Palma,
-
- MaxControllers,
-};
-
-class IAppletResource final : public ServiceFramework<IAppletResource> {
-public:
- explicit IAppletResource(Core::System& system_,
- KernelHelpers::ServiceContext& service_context_);
- ~IAppletResource() override;
-
- void ActivateController(HidController controller);
- void DeactivateController(HidController controller);
-
- template <typename T>
- T& GetController(HidController controller) {
- return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
- }
-
- template <typename T>
- const T& GetController(HidController controller) const {
- return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
- }
-
-private:
- template <typename T>
- void MakeController(HidController controller, u8* shared_memory) {
- if constexpr (std::is_constructible_v<T, Core::System&, u8*>) {
- controllers[static_cast<std::size_t>(controller)] =
- std::make_unique<T>(system, shared_memory);
- } else {
- controllers[static_cast<std::size_t>(controller)] =
- std::make_unique<T>(system.HIDCore(), shared_memory);
- }
- }
-
- template <typename T>
- void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
- controllers[static_cast<std::size_t>(controller)] =
- std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
- }
-
- void GetSharedMemoryHandle(HLERequestContext& ctx);
- void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
- void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
- void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
- void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
-
- KernelHelpers::ServiceContext& service_context;
-
- std::shared_ptr<Core::Timing::EventType> npad_update_event;
- std::shared_ptr<Core::Timing::EventType> default_update_event;
- std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
- std::shared_ptr<Core::Timing::EventType> motion_update_event;
-
- std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
- controllers{};
-};
-
-class Hid final : public ServiceFramework<Hid> {
-public:
- explicit Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_);
- ~Hid() override;
-
- std::shared_ptr<IAppletResource> GetAppletResource();
-
-private:
- void CreateAppletResource(HLERequestContext& ctx);
- void ActivateDebugPad(HLERequestContext& ctx);
- void ActivateTouchScreen(HLERequestContext& ctx);
- void ActivateMouse(HLERequestContext& ctx);
- void ActivateKeyboard(HLERequestContext& ctx);
- void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
- void ActivateXpad(HLERequestContext& ctx);
- void GetXpadIDs(HLERequestContext& ctx);
- void ActivateSixAxisSensor(HLERequestContext& ctx);
- void DeactivateSixAxisSensor(HLERequestContext& ctx);
- void StartSixAxisSensor(HLERequestContext& ctx);
- void StopSixAxisSensor(HLERequestContext& ctx);
- void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
- void EnableSixAxisSensorFusion(HLERequestContext& ctx);
- void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
- void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
- void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
- void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
- void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
- void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
- void IsSixAxisSensorAtRest(HLERequestContext& ctx);
- void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
- void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
- void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
- void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
- void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
- void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
- void ActivateGesture(HLERequestContext& ctx);
- void SetSupportedNpadStyleSet(HLERequestContext& ctx);
- void GetSupportedNpadStyleSet(HLERequestContext& ctx);
- void SetSupportedNpadIdType(HLERequestContext& ctx);
- void ActivateNpad(HLERequestContext& ctx);
- void DeactivateNpad(HLERequestContext& ctx);
- void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
- void DisconnectNpad(HLERequestContext& ctx);
- void GetPlayerLedPattern(HLERequestContext& ctx);
- void ActivateNpadWithRevision(HLERequestContext& ctx);
- void SetNpadJoyHoldType(HLERequestContext& ctx);
- void GetNpadJoyHoldType(HLERequestContext& ctx);
- void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
- void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
- void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
- void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
- void StartLrAssignmentMode(HLERequestContext& ctx);
- void StopLrAssignmentMode(HLERequestContext& ctx);
- void SetNpadHandheldActivationMode(HLERequestContext& ctx);
- void GetNpadHandheldActivationMode(HLERequestContext& ctx);
- void SwapNpadAssignment(HLERequestContext& ctx);
- void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
- void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
- void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
- void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
- void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
- void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
- void GetVibrationDeviceInfo(HLERequestContext& ctx);
- void SendVibrationValue(HLERequestContext& ctx);
- void GetActualVibrationValue(HLERequestContext& ctx);
- void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
- void PermitVibration(HLERequestContext& ctx);
- void IsVibrationPermitted(HLERequestContext& ctx);
- void SendVibrationValues(HLERequestContext& ctx);
- void SendVibrationGcErmCommand(HLERequestContext& ctx);
- void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
- void BeginPermitVibrationSession(HLERequestContext& ctx);
- void EndPermitVibrationSession(HLERequestContext& ctx);
- void IsVibrationDeviceMounted(HLERequestContext& ctx);
- void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
- void StartConsoleSixAxisSensor(HLERequestContext& ctx);
- void StopConsoleSixAxisSensor(HLERequestContext& ctx);
- void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
- void StartSevenSixAxisSensor(HLERequestContext& ctx);
- void StopSevenSixAxisSensor(HLERequestContext& ctx);
- void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
- void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
- void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
- void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
- void GetPalmaConnectionHandle(HLERequestContext& ctx);
- void InitializePalma(HLERequestContext& ctx);
- void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
- void GetPalmaOperationInfo(HLERequestContext& ctx);
- void PlayPalmaActivity(HLERequestContext& ctx);
- void SetPalmaFrModeType(HLERequestContext& ctx);
- void ReadPalmaStep(HLERequestContext& ctx);
- void EnablePalmaStep(HLERequestContext& ctx);
- void ResetPalmaStep(HLERequestContext& ctx);
- void ReadPalmaApplicationSection(HLERequestContext& ctx);
- void WritePalmaApplicationSection(HLERequestContext& ctx);
- void ReadPalmaUniqueCode(HLERequestContext& ctx);
- void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
- void WritePalmaActivityEntry(HLERequestContext& ctx);
- void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
- void WritePalmaWaveEntry(HLERequestContext& ctx);
- void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
- void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
- void SuspendPalmaFeature(HLERequestContext& ctx);
- void GetPalmaOperationResult(HLERequestContext& ctx);
- void ReadPalmaPlayLog(HLERequestContext& ctx);
- void ResetPalmaPlayLog(HLERequestContext& ctx);
- void SetIsPalmaAllConnectable(HLERequestContext& ctx);
- void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
- void PairPalma(HLERequestContext& ctx);
- void SetPalmaBoostMode(HLERequestContext& ctx);
- void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
- void EnablePalmaBoostMode(HLERequestContext& ctx);
- void GetPalmaBluetoothAddress(HLERequestContext& ctx);
- void SetDisallowedPalmaConnection(HLERequestContext& ctx);
- void SetNpadCommunicationMode(HLERequestContext& ctx);
- void GetNpadCommunicationMode(HLERequestContext& ctx);
- void SetTouchScreenConfiguration(HLERequestContext& ctx);
- void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
-
- std::shared_ptr<IAppletResource> applet_resource;
-
- KernelHelpers::ServiceContext service_context;
-};
-
void LoopProcess(Core::System& system);
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp
new file mode 100644
index 000000000..6294f3dfb
--- /dev/null
+++ b/src/core/hle/service/hid/hid_debug_server.cpp
@@ -0,0 +1,159 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/hle/service/hid/hid_debug_server.h"
+#include "core/hle/service/hid/resource_manager.h"
+#include "core/hle/service/ipc_helpers.h"
+
+namespace Service::HID {
+
+IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
+ : ServiceFramework{system_, "hid:dbg"}, resource_manager{resource} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "DeactivateDebugPad"},
+ {1, nullptr, "SetDebugPadAutoPilotState"},
+ {2, nullptr, "UnsetDebugPadAutoPilotState"},
+ {10, nullptr, "DeactivateTouchScreen"},
+ {11, nullptr, "SetTouchScreenAutoPilotState"},
+ {12, nullptr, "UnsetTouchScreenAutoPilotState"},
+ {13, nullptr, "GetTouchScreenConfiguration"},
+ {14, nullptr, "ProcessTouchScreenAutoTune"},
+ {15, nullptr, "ForceStopTouchScreenManagement"},
+ {16, nullptr, "ForceRestartTouchScreenManagement"},
+ {17, nullptr, "IsTouchScreenManaged"},
+ {20, nullptr, "DeactivateMouse"},
+ {21, nullptr, "SetMouseAutoPilotState"},
+ {22, nullptr, "UnsetMouseAutoPilotState"},
+ {25, nullptr, "SetDebugMouseAutoPilotState"},
+ {26, nullptr, "UnsetDebugMouseAutoPilotState"},
+ {30, nullptr, "DeactivateKeyboard"},
+ {31, nullptr, "SetKeyboardAutoPilotState"},
+ {32, nullptr, "UnsetKeyboardAutoPilotState"},
+ {50, nullptr, "DeactivateXpad"},
+ {51, nullptr, "SetXpadAutoPilotState"},
+ {52, nullptr, "UnsetXpadAutoPilotState"},
+ {53, nullptr, "DeactivateJoyXpad"},
+ {60, nullptr, "ClearNpadSystemCommonPolicy"},
+ {61, nullptr, "DeactivateNpad"},
+ {62, nullptr, "ForceDisconnectNpad"},
+ {91, nullptr, "DeactivateGesture"},
+ {110, nullptr, "DeactivateHomeButton"},
+ {111, nullptr, "SetHomeButtonAutoPilotState"},
+ {112, nullptr, "UnsetHomeButtonAutoPilotState"},
+ {120, nullptr, "DeactivateSleepButton"},
+ {121, nullptr, "SetSleepButtonAutoPilotState"},
+ {122, nullptr, "UnsetSleepButtonAutoPilotState"},
+ {123, nullptr, "DeactivateInputDetector"},
+ {130, nullptr, "DeactivateCaptureButton"},
+ {131, nullptr, "SetCaptureButtonAutoPilotState"},
+ {132, nullptr, "UnsetCaptureButtonAutoPilotState"},
+ {133, nullptr, "SetShiftAccelerometerCalibrationValue"},
+ {134, nullptr, "GetShiftAccelerometerCalibrationValue"},
+ {135, nullptr, "SetShiftGyroscopeCalibrationValue"},
+ {136, nullptr, "GetShiftGyroscopeCalibrationValue"},
+ {140, nullptr, "DeactivateConsoleSixAxisSensor"},
+ {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
+ {142, nullptr, "DeactivateSevenSixAxisSensor"},
+ {143, nullptr, "GetConsoleSixAxisSensorCountStates"},
+ {144, nullptr, "GetAccelerometerFsr"},
+ {145, nullptr, "SetAccelerometerFsr"},
+ {146, nullptr, "GetAccelerometerOdr"},
+ {147, nullptr, "SetAccelerometerOdr"},
+ {148, nullptr, "GetGyroscopeFsr"},
+ {149, nullptr, "SetGyroscopeFsr"},
+ {150, nullptr, "GetGyroscopeOdr"},
+ {151, nullptr, "SetGyroscopeOdr"},
+ {152, nullptr, "GetWhoAmI"},
+ {201, nullptr, "ActivateFirmwareUpdate"},
+ {202, nullptr, "DeactivateFirmwareUpdate"},
+ {203, nullptr, "StartFirmwareUpdate"},
+ {204, nullptr, "GetFirmwareUpdateStage"},
+ {205, nullptr, "GetFirmwareVersion"},
+ {206, nullptr, "GetDestinationFirmwareVersion"},
+ {207, nullptr, "DiscardFirmwareInfoCacheForRevert"},
+ {208, nullptr, "StartFirmwareUpdateForRevert"},
+ {209, nullptr, "GetAvailableFirmwareVersionForRevert"},
+ {210, nullptr, "IsFirmwareUpdatingDevice"},
+ {211, nullptr, "StartFirmwareUpdateIndividual"},
+ {215, nullptr, "SetUsbFirmwareForceUpdateEnabled"},
+ {216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"},
+ {221, nullptr, "UpdateControllerColor"},
+ {222, nullptr, "ConnectUsbPadsAsync"},
+ {223, nullptr, "DisconnectUsbPadsAsync"},
+ {224, nullptr, "UpdateDesignInfo"},
+ {225, nullptr, "GetUniquePadDriverState"},
+ {226, nullptr, "GetSixAxisSensorDriverStates"},
+ {227, nullptr, "GetRxPacketHistory"},
+ {228, nullptr, "AcquireOperationEventHandle"},
+ {229, nullptr, "ReadSerialFlash"},
+ {230, nullptr, "WriteSerialFlash"},
+ {231, nullptr, "GetOperationResult"},
+ {232, nullptr, "EnableShipmentMode"},
+ {233, nullptr, "ClearPairingInfo"},
+ {234, nullptr, "GetUniquePadDeviceTypeSetInternal"},
+ {235, nullptr, "EnableAnalogStickPower"},
+ {236, nullptr, "RequestKuinaUartClockCal"},
+ {237, nullptr, "GetKuinaUartClockCal"},
+ {238, nullptr, "SetKuinaUartClockTrim"},
+ {239, nullptr, "KuinaLoopbackTest"},
+ {240, nullptr, "RequestBatteryVoltage"},
+ {241, nullptr, "GetBatteryVoltage"},
+ {242, nullptr, "GetUniquePadPowerInfo"},
+ {243, nullptr, "RebootUniquePad"},
+ {244, nullptr, "RequestKuinaFirmwareVersion"},
+ {245, nullptr, "GetKuinaFirmwareVersion"},
+ {246, nullptr, "GetVidPid"},
+ {247, nullptr, "GetAnalogStickCalibrationValue"},
+ {248, nullptr, "GetUniquePadIdsFull"},
+ {249, nullptr, "ConnectUniquePad"},
+ {250, nullptr, "IsVirtual"},
+ {251, nullptr, "GetAnalogStickModuleParam"},
+ {301, nullptr, "GetAbstractedPadHandles"},
+ {302, nullptr, "GetAbstractedPadState"},
+ {303, nullptr, "GetAbstractedPadsState"},
+ {321, nullptr, "SetAutoPilotVirtualPadState"},
+ {322, nullptr, "UnsetAutoPilotVirtualPadState"},
+ {323, nullptr, "UnsetAllAutoPilotVirtualPadState"},
+ {324, nullptr, "AttachHdlsWorkBuffer"},
+ {325, nullptr, "ReleaseHdlsWorkBuffer"},
+ {326, nullptr, "DumpHdlsNpadAssignmentState"},
+ {327, nullptr, "DumpHdlsStates"},
+ {328, nullptr, "ApplyHdlsNpadAssignmentState"},
+ {329, nullptr, "ApplyHdlsStateList"},
+ {330, nullptr, "AttachHdlsVirtualDevice"},
+ {331, nullptr, "DetachHdlsVirtualDevice"},
+ {332, nullptr, "SetHdlsState"},
+ {350, nullptr, "AddRegisteredDevice"},
+ {400, nullptr, "DisableExternalMcuOnNxDevice"},
+ {401, nullptr, "DisableRailDeviceFiltering"},
+ {402, nullptr, "EnableWiredPairing"},
+ {403, nullptr, "EnableShipmentModeAutoClear"},
+ {404, nullptr, "SetRailEnabled"},
+ {500, nullptr, "SetFactoryInt"},
+ {501, nullptr, "IsFactoryBootEnabled"},
+ {550, nullptr, "SetAnalogStickModelDataTemporarily"},
+ {551, nullptr, "GetAnalogStickModelData"},
+ {552, nullptr, "ResetAnalogStickModelData"},
+ {600, nullptr, "ConvertPadState"},
+ {650, nullptr, "AddButtonPlayData"},
+ {651, nullptr, "StartButtonPlayData"},
+ {652, nullptr, "StopButtonPlayData"},
+ {2000, nullptr, "DeactivateDigitizer"},
+ {2001, nullptr, "SetDigitizerAutoPilotState"},
+ {2002, nullptr, "UnsetDigitizerAutoPilotState"},
+ {2002, nullptr, "ReloadFirmwareDebugSettings"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+IHidDebugServer::~IHidDebugServer() = default;
+
+std::shared_ptr<ResourceManager> IHidDebugServer::GetResourceManager() {
+ resource_manager->Initialize();
+ return resource_manager;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_debug_server.h b/src/core/hle/service/hid/hid_debug_server.h
new file mode 100644
index 000000000..406db2211
--- /dev/null
+++ b/src/core/hle/service/hid/hid_debug_server.h
@@ -0,0 +1,26 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Core {
+class System;
+}
+
+namespace Service::HID {
+class ResourceManager;
+
+class IHidDebugServer final : public ServiceFramework<IHidDebugServer> {
+public:
+ explicit IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
+ ~IHidDebugServer() override;
+
+private:
+ std::shared_ptr<ResourceManager> GetResourceManager();
+
+ std::shared_ptr<ResourceManager> resource_manager;
+};
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_firmware_settings.cpp b/src/core/hle/service/hid/hid_firmware_settings.cpp
new file mode 100644
index 000000000..59bd6825c
--- /dev/null
+++ b/src/core/hle/service/hid/hid_firmware_settings.cpp
@@ -0,0 +1,99 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/hle/service/hid/hid_firmware_settings.h"
+
+namespace Service::HID {
+
+HidFirmwareSettings::HidFirmwareSettings() {
+ LoadSettings(true);
+}
+
+void HidFirmwareSettings::Reload() {
+ LoadSettings(true);
+}
+
+void HidFirmwareSettings::LoadSettings(bool reload_config) {
+ if (is_initalized && !reload_config) {
+ return;
+ }
+
+ // TODO: Use nn::settings::fwdbg::GetSettingsItemValue to load config values
+
+ is_debug_pad_enabled = true;
+ is_device_managed = true;
+ is_touch_i2c_managed = is_device_managed;
+ is_future_devices_emulated = false;
+ is_mcu_hardware_error_emulated = false;
+ is_rail_enabled = true;
+ is_firmware_update_failure_emulated = false;
+ is_firmware_update_failure = {};
+ is_ble_disabled = false;
+ is_dscale_disabled = false;
+ is_handheld_forced = true;
+ features_per_id_disabled = {};
+ is_touch_firmware_auto_update_disabled = false;
+ is_initalized = true;
+}
+
+bool HidFirmwareSettings::IsDebugPadEnabled() {
+ LoadSettings(false);
+ return is_debug_pad_enabled;
+}
+
+bool HidFirmwareSettings::IsDeviceManaged() {
+ LoadSettings(false);
+ return is_device_managed;
+}
+
+bool HidFirmwareSettings::IsEmulateFutureDevice() {
+ LoadSettings(false);
+ return is_future_devices_emulated;
+}
+
+bool HidFirmwareSettings::IsTouchI2cManaged() {
+ LoadSettings(false);
+ return is_touch_i2c_managed;
+}
+
+bool HidFirmwareSettings::IsHandheldForced() {
+ LoadSettings(false);
+ return is_handheld_forced;
+}
+
+bool HidFirmwareSettings::IsRailEnabled() {
+ LoadSettings(false);
+ return is_rail_enabled;
+}
+
+bool HidFirmwareSettings::IsHardwareErrorEmulated() {
+ LoadSettings(false);
+ return is_mcu_hardware_error_emulated;
+}
+
+bool HidFirmwareSettings::IsBleDisabled() {
+ LoadSettings(false);
+ return is_ble_disabled;
+}
+
+bool HidFirmwareSettings::IsDscaleDisabled() {
+ LoadSettings(false);
+ return is_dscale_disabled;
+}
+
+bool HidFirmwareSettings::IsTouchAutoUpdateDisabled() {
+ LoadSettings(false);
+ return is_touch_firmware_auto_update_disabled;
+}
+
+HidFirmwareSettings::FirmwareSetting HidFirmwareSettings::GetFirmwareUpdateFailure() {
+ LoadSettings(false);
+ return is_firmware_update_failure;
+}
+
+HidFirmwareSettings::FeaturesPerId HidFirmwareSettings::FeaturesDisabledPerId() {
+ LoadSettings(false);
+ return features_per_id_disabled;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_firmware_settings.h b/src/core/hle/service/hid/hid_firmware_settings.h
new file mode 100644
index 000000000..6c10c440b
--- /dev/null
+++ b/src/core/hle/service/hid/hid_firmware_settings.h
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "common/common_types.h"
+
+namespace Service::HID {
+
+/// Loads firmware config from nn::settings::fwdbg
+class HidFirmwareSettings {
+public:
+ using FirmwareSetting = std::array<u8, 4>;
+ using FeaturesPerId = std::array<bool, 0xA8>;
+
+ HidFirmwareSettings();
+
+ void Reload();
+ void LoadSettings(bool reload_config);
+
+ bool IsDebugPadEnabled();
+ bool IsDeviceManaged();
+ bool IsEmulateFutureDevice();
+ bool IsTouchI2cManaged();
+ bool IsHandheldForced();
+ bool IsRailEnabled();
+ bool IsHardwareErrorEmulated();
+ bool IsBleDisabled();
+ bool IsDscaleDisabled();
+ bool IsTouchAutoUpdateDisabled();
+
+ FirmwareSetting GetFirmwareUpdateFailure();
+ FeaturesPerId FeaturesDisabledPerId();
+
+private:
+ bool is_initalized{};
+
+ // Debug settings
+ bool is_debug_pad_enabled{};
+ bool is_device_managed{};
+ bool is_touch_i2c_managed{};
+ bool is_future_devices_emulated{};
+ bool is_mcu_hardware_error_emulated{};
+ bool is_rail_enabled{};
+ bool is_firmware_update_failure_emulated{};
+ bool is_ble_disabled{};
+ bool is_dscale_disabled{};
+ bool is_handheld_forced{};
+ bool is_touch_firmware_auto_update_disabled{};
+ FirmwareSetting is_firmware_update_failure{};
+ FeaturesPerId features_per_id_disabled{};
+};
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
new file mode 100644
index 000000000..583142e35
--- /dev/null
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -0,0 +1,2371 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <array>
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "common/settings.h"
+#include "core/hid/hid_core.h"
+#include "core/hle/kernel/k_shared_memory.h"
+#include "core/hle/kernel/k_transfer_memory.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/service/hid/errors.h"
+#include "core/hle/service/hid/hid_firmware_settings.h"
+#include "core/hle/service/hid/hid_server.h"
+#include "core/hle/service/hid/hid_util.h"
+#include "core/hle/service/hid/resource_manager.h"
+#include "core/hle/service/ipc_helpers.h"
+#include "core/memory.h"
+
+#include "core/hle/service/hid/controllers/console_six_axis.h"
+#include "core/hle/service/hid/controllers/controller_base.h"
+#include "core/hle/service/hid/controllers/debug_pad.h"
+#include "core/hle/service/hid/controllers/gesture.h"
+#include "core/hle/service/hid/controllers/keyboard.h"
+#include "core/hle/service/hid/controllers/mouse.h"
+#include "core/hle/service/hid/controllers/npad.h"
+#include "core/hle/service/hid/controllers/palma.h"
+#include "core/hle/service/hid/controllers/seven_six_axis.h"
+#include "core/hle/service/hid/controllers/six_axis.h"
+#include "core/hle/service/hid/controllers/touchscreen.h"
+
+namespace Service::HID {
+
+class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
+public:
+ explicit IActiveVibrationDeviceList(Core::System& system_,
+ std::shared_ptr<ResourceManager> resource)
+ : ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void InitializeVibrationDevice(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
+
+ if (resource_manager != nullptr) {
+ resource_manager->GetNpad()->InitializeVibrationDevice(vibration_device_handle);
+ }
+
+ LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
+ vibration_device_handle.npad_type, vibration_device_handle.npad_id,
+ vibration_device_handle.device_index);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ std::shared_ptr<ResourceManager> resource_manager;
+};
+
+IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource,
+ std::shared_ptr<HidFirmwareSettings> settings)
+ : ServiceFramework{system_, "hid"}, resource_manager{resource}, firmware_settings{settings} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &IHidServer::CreateAppletResource, "CreateAppletResource"},
+ {1, &IHidServer::ActivateDebugPad, "ActivateDebugPad"},
+ {11, &IHidServer::ActivateTouchScreen, "ActivateTouchScreen"},
+ {21, &IHidServer::ActivateMouse, "ActivateMouse"},
+ {26, nullptr, "ActivateDebugMouse"},
+ {31, &IHidServer::ActivateKeyboard, "ActivateKeyboard"},
+ {32, &IHidServer::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"},
+ {40, &IHidServer::AcquireXpadIdEventHandle, "AcquireXpadIdEventHandle"},
+ {41, &IHidServer::ReleaseXpadIdEventHandle, "ReleaseXpadIdEventHandle"},
+ {51, &IHidServer::ActivateXpad, "ActivateXpad"},
+ {55, &IHidServer::GetXpadIds, "GetXpadIds"},
+ {56, &IHidServer::ActivateJoyXpad, "ActivateJoyXpad"},
+ {58, &IHidServer::GetJoyXpadLifoHandle, "GetJoyXpadLifoHandle"},
+ {59, &IHidServer::GetJoyXpadIds, "GetJoyXpadIds"},
+ {60, &IHidServer::ActivateSixAxisSensor, "ActivateSixAxisSensor"},
+ {61, &IHidServer::DeactivateSixAxisSensor, "DeactivateSixAxisSensor"},
+ {62, &IHidServer::GetSixAxisSensorLifoHandle, "GetSixAxisSensorLifoHandle"},
+ {63, &IHidServer::ActivateJoySixAxisSensor, "ActivateJoySixAxisSensor"},
+ {64, &IHidServer::DeactivateJoySixAxisSensor, "DeactivateJoySixAxisSensor"},
+ {65, &IHidServer::GetJoySixAxisSensorLifoHandle, "GetJoySixAxisSensorLifoHandle"},
+ {66, &IHidServer::StartSixAxisSensor, "StartSixAxisSensor"},
+ {67, &IHidServer::StopSixAxisSensor, "StopSixAxisSensor"},
+ {68, &IHidServer::IsSixAxisSensorFusionEnabled, "IsSixAxisSensorFusionEnabled"},
+ {69, &IHidServer::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
+ {70, &IHidServer::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"},
+ {71, &IHidServer::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"},
+ {72, &IHidServer::ResetSixAxisSensorFusionParameters, "ResetSixAxisSensorFusionParameters"},
+ {73, nullptr, "SetAccelerometerParameters"},
+ {74, nullptr, "GetAccelerometerParameters"},
+ {75, nullptr, "ResetAccelerometerParameters"},
+ {76, nullptr, "SetAccelerometerPlayMode"},
+ {77, nullptr, "GetAccelerometerPlayMode"},
+ {78, nullptr, "ResetAccelerometerPlayMode"},
+ {79, &IHidServer::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
+ {80, &IHidServer::GetGyroscopeZeroDriftMode, "GetGyroscopeZeroDriftMode"},
+ {81, &IHidServer::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"},
+ {82, &IHidServer::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
+ {83, &IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"},
+ {84, &IHidServer::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"},
+ {85, &IHidServer::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"},
+ {86, nullptr, "StoreSixAxisSensorCalibrationParameter"},
+ {87, &IHidServer::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"},
+ {88, &IHidServer::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"},
+ {89, &IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"},
+ {91, &IHidServer::ActivateGesture, "ActivateGesture"},
+ {100, &IHidServer::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
+ {101, &IHidServer::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
+ {102, &IHidServer::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
+ {103, &IHidServer::ActivateNpad, "ActivateNpad"},
+ {104, &IHidServer::DeactivateNpad, "DeactivateNpad"},
+ {106, &IHidServer::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
+ {107, &IHidServer::DisconnectNpad, "DisconnectNpad"},
+ {108, &IHidServer::GetPlayerLedPattern, "GetPlayerLedPattern"},
+ {109, &IHidServer::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
+ {120, &IHidServer::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
+ {121, &IHidServer::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
+ {122, &IHidServer::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
+ {123, &IHidServer::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"},
+ {124, &IHidServer::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
+ {125, &IHidServer::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
+ {126, &IHidServer::StartLrAssignmentMode, "StartLrAssignmentMode"},
+ {127, &IHidServer::StopLrAssignmentMode, "StopLrAssignmentMode"},
+ {128, &IHidServer::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
+ {129, &IHidServer::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
+ {130, &IHidServer::SwapNpadAssignment, "SwapNpadAssignment"},
+ {131, &IHidServer::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
+ {132, &IHidServer::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
+ {133, &IHidServer::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"},
+ {134, &IHidServer::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"},
+ {135, &IHidServer::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"},
+ {136, &IHidServer::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"},
+ {200, &IHidServer::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
+ {201, &IHidServer::SendVibrationValue, "SendVibrationValue"},
+ {202, &IHidServer::GetActualVibrationValue, "GetActualVibrationValue"},
+ {203, &IHidServer::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
+ {204, &IHidServer::PermitVibration, "PermitVibration"},
+ {205, &IHidServer::IsVibrationPermitted, "IsVibrationPermitted"},
+ {206, &IHidServer::SendVibrationValues, "SendVibrationValues"},
+ {207, &IHidServer::SendVibrationGcErmCommand, "SendVibrationGcErmCommand"},
+ {208, &IHidServer::GetActualVibrationGcErmCommand, "GetActualVibrationGcErmCommand"},
+ {209, &IHidServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
+ {210, &IHidServer::EndPermitVibrationSession, "EndPermitVibrationSession"},
+ {211, &IHidServer::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
+ {212, nullptr, "SendVibrationValueInBool"},
+ {300, &IHidServer::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
+ {301, &IHidServer::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
+ {302, &IHidServer::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
+ {303, &IHidServer::ActivateSevenSixAxisSensor, "ActivateSevenSixAxisSensor"},
+ {304, &IHidServer::StartSevenSixAxisSensor, "StartSevenSixAxisSensor"},
+ {305, &IHidServer::StopSevenSixAxisSensor, "StopSevenSixAxisSensor"},
+ {306, &IHidServer::InitializeSevenSixAxisSensor, "InitializeSevenSixAxisSensor"},
+ {307, &IHidServer::FinalizeSevenSixAxisSensor, "FinalizeSevenSixAxisSensor"},
+ {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
+ {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
+ {310, &IHidServer::ResetSevenSixAxisSensorTimestamp, "ResetSevenSixAxisSensorTimestamp"},
+ {400, &IHidServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
+ {401, nullptr, "EnableUsbFullKeyController"},
+ {402, nullptr, "IsUsbFullKeyControllerConnected"},
+ {403, nullptr, "HasBattery"},
+ {404, nullptr, "HasLeftRightBattery"},
+ {405, nullptr, "GetNpadInterfaceType"},
+ {406, nullptr, "GetNpadLeftRightInterfaceType"},
+ {407, nullptr, "GetNpadOfHighestBatteryLevel"},
+ {408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"},
+ {500, &IHidServer::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"},
+ {501, &IHidServer::InitializePalma, "InitializePalma"},
+ {502, &IHidServer::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"},
+ {503, &IHidServer::GetPalmaOperationInfo, "GetPalmaOperationInfo"},
+ {504, &IHidServer::PlayPalmaActivity, "PlayPalmaActivity"},
+ {505, &IHidServer::SetPalmaFrModeType, "SetPalmaFrModeType"},
+ {506, &IHidServer::ReadPalmaStep, "ReadPalmaStep"},
+ {507, &IHidServer::EnablePalmaStep, "EnablePalmaStep"},
+ {508, &IHidServer::ResetPalmaStep, "ResetPalmaStep"},
+ {509, &IHidServer::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"},
+ {510, &IHidServer::WritePalmaApplicationSection, "WritePalmaApplicationSection"},
+ {511, &IHidServer::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"},
+ {512, &IHidServer::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"},
+ {513, &IHidServer::WritePalmaActivityEntry, "WritePalmaActivityEntry"},
+ {514, &IHidServer::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"},
+ {515, &IHidServer::WritePalmaWaveEntry, "WritePalmaWaveEntry"},
+ {516, &IHidServer::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"},
+ {517, &IHidServer::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"},
+ {518, &IHidServer::SuspendPalmaFeature, "SuspendPalmaFeature"},
+ {519, &IHidServer::GetPalmaOperationResult, "GetPalmaOperationResult"},
+ {520, &IHidServer::ReadPalmaPlayLog, "ReadPalmaPlayLog"},
+ {521, &IHidServer::ResetPalmaPlayLog, "ResetPalmaPlayLog"},
+ {522, &IHidServer::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
+ {523, &IHidServer::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"},
+ {524, &IHidServer::PairPalma, "PairPalma"},
+ {525, &IHidServer::SetPalmaBoostMode, "SetPalmaBoostMode"},
+ {526, &IHidServer::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"},
+ {527, &IHidServer::EnablePalmaBoostMode, "EnablePalmaBoostMode"},
+ {528, &IHidServer::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"},
+ {529, &IHidServer::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"},
+ {1000, &IHidServer::SetNpadCommunicationMode, "SetNpadCommunicationMode"},
+ {1001, &IHidServer::GetNpadCommunicationMode, "GetNpadCommunicationMode"},
+ {1002, &IHidServer::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"},
+ {1003, &IHidServer::IsFirmwareUpdateNeededForNotification, "IsFirmwareUpdateNeededForNotification"},
+ {2000, nullptr, "ActivateDigitizer"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+IHidServer::~IHidServer() = default;
+
+void IHidServer::CreateAppletResource(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(ResultSuccess);
+ rb.PushIpcInterface<IAppletResource>(system, resource_manager);
+}
+
+void IHidServer::ActivateDebugPad(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ Result result = ResultSuccess;
+ auto debug_pad = GetResourceManager()->GetDebugPad();
+
+ if (!firmware_settings->IsDeviceManaged()) {
+ result = debug_pad->Activate();
+ }
+
+ if (result.IsSuccess()) {
+ result = debug_pad->Activate(applet_resource_user_id);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ActivateTouchScreen(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ Result result = ResultSuccess;
+ auto touch_screen = GetResourceManager()->GetTouchScreen();
+
+ if (!firmware_settings->IsDeviceManaged()) {
+ result = touch_screen->Activate();
+ }
+
+ if (result.IsSuccess()) {
+ result = touch_screen->Activate(applet_resource_user_id);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ActivateMouse(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ Result result = ResultSuccess;
+ auto mouse = GetResourceManager()->GetMouse();
+
+ if (!firmware_settings->IsDeviceManaged()) {
+ result = mouse->Activate();
+ }
+
+ if (result.IsSuccess()) {
+ result = mouse->Activate(applet_resource_user_id);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ActivateKeyboard(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ Result result = ResultSuccess;
+ auto keyboard = GetResourceManager()->GetKeyboard();
+
+ if (!firmware_settings->IsDeviceManaged()) {
+ result = keyboard->Activate();
+ }
+
+ if (result.IsSuccess()) {
+ result = keyboard->Activate(applet_resource_user_id);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::SendKeyboardLockKeyEvent(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto flags{rp.Pop<u32>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::AcquireXpadIdEventHandle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ // Handle returned is null here
+}
+
+void IHidServer::ReleaseXpadIdEventHandle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::ActivateXpad(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ u32 basic_xpad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
+ parameters.basic_xpad_id, parameters.applet_resource_user_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetXpadIds(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_HID, "called");
+
+ // This function has been hardcoded since 10.0.0+
+ const std::array<u32, 4> basic_xpad_id{0, 1, 2, 3};
+ ctx.WriteBuffer(basic_xpad_id);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<s64>(basic_xpad_id.size());
+}
+
+void IHidServer::ActivateJoyXpad(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetJoyXpadLifoHandle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ // Handle returned is null here
+}
+
+void IHidServer::GetJoyXpadIds(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_HID, "called");
+
+ // This function has been hardcoded since 10.0.0+
+ const s64 basic_xpad_id_count{};
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push(basic_xpad_id_count);
+}
+
+void IHidServer::ActivateSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::DeactivateSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetSixAxisSensorLifoHandle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::ActivateJoySixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::DeactivateJoySixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetJoySixAxisSensorLifoHandle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto joy_xpad_id{rp.Pop<u32>()};
+
+ LOG_DEBUG(Service_HID, "called, joy_xpad_id={}", joy_xpad_id);
+
+ // This function has been stubbed since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ // Handle returned is null here
+}
+
+void IHidServer::StartSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->SetSixAxisEnabled(parameters.sixaxis_handle, true);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::StopSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->SetSixAxisEnabled(parameters.sixaxis_handle, false);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ bool is_enabled{};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result =
+ six_axis->IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.Push(is_enabled);
+}
+
+void IHidServer::EnableSixAxisSensorFusion(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool enable_sixaxis_sensor_fusion;
+ INSERT_PADDING_BYTES_NOINIT(3);
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->SetSixAxisFusionEnabled(parameters.sixaxis_handle,
+ parameters.enable_sixaxis_sensor_fusion);
+
+ LOG_DEBUG(Service_HID,
+ "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
+ "device_index={}, applet_resource_user_id={}",
+ parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type,
+ parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
+ parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ Core::HID::SixAxisSensorFusionParameters sixaxis_fusion;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result =
+ six_axis->SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
+ "parameter2={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1,
+ parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::SixAxisSensorFusionParameters fusion_parameters{};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result =
+ six_axis->GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result);
+ rb.PushRaw(fusion_parameters);
+}
+
+void IHidServer::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ // Since these parameters are unknown just use what HW outputs
+ const Core::HID::SixAxisSensorFusionParameters fusion_parameters{
+ .parameter1 = 0.03f,
+ .parameter2 = 0.4f,
+ };
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result1 =
+ six_axis->SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
+ const auto result2 = six_axis->SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ if (result1.IsError()) {
+ rb.Push(result1);
+ return;
+ }
+ rb.Push(result2);
+}
+
+void IHidServer::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()};
+ const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
+ "applet_resource_user_id={}",
+ sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index,
+ drift_mode, applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.PushEnum(drift_mode);
+}
+
+void IHidServer::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::IsSixAxisSensorAtRest(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ bool is_at_rest{};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ six_axis->IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(is_at_rest);
+}
+
+void IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ bool is_firmware_available{};
+ auto controller = GetResourceManager()->GetNpad();
+ controller->IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
+ is_firmware_available);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(is_firmware_available);
+}
+
+void IHidServer::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool enabled;
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->EnableSixAxisSensorUnalteredPassthrough(parameters.sixaxis_handle,
+ parameters.enabled);
+
+ LOG_DEBUG(Service_HID,
+ "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, "
+ "applet_resource_user_id={}",
+ parameters.enabled, parameters.sixaxis_handle.npad_type,
+ parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
+ parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ bool is_unaltered_sisxaxis_enabled{};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result = six_axis->IsSixAxisSensorUnalteredPassthroughEnabled(
+ parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled);
+
+ LOG_DEBUG(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.Push(is_unaltered_sisxaxis_enabled);
+}
+
+void IHidServer::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::SixAxisSensorCalibrationParameter calibration{};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result =
+ six_axis->LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ if (result.IsSuccess()) {
+ ctx.WriteBuffer(calibration);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::GetSixAxisSensorIcInformation(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::SixAxisSensorIcInformation ic_information{};
+ auto six_axis = GetResourceManager()->GetSixAxis();
+ const auto result =
+ six_axis->GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ if (result.IsSuccess()) {
+ ctx.WriteBuffer(ic_information);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::SixAxisSensorHandle sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto controller = GetResourceManager()->GetNpad();
+ const auto result =
+ controller->ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ActivateGesture(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ u32 basic_gesture_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_INFO(Service_HID, "called, basic_gesture_id={}, applet_resource_user_id={}",
+ parameters.basic_gesture_id, parameters.applet_resource_user_id);
+
+ Result result = ResultSuccess;
+ auto gesture = GetResourceManager()->GetGesture();
+
+ if (!firmware_settings->IsDeviceManaged()) {
+ result = gesture->Activate();
+ }
+
+ if (result.IsSuccess()) {
+ // TODO: Use gesture id here
+ result = gesture->Activate(parameters.applet_resource_user_id);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadStyleSet supported_styleset;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ GetResourceManager()->GetNpad()->SetSupportedStyleSet({parameters.supported_styleset});
+
+ LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
+ parameters.supported_styleset, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw);
+}
+
+void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ const auto result = GetResourceManager()->GetNpad()->SetSupportedNpadIdTypes(ctx.ReadBuffer());
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ActivateNpad(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ auto npad = GetResourceManager()->GetNpad();
+
+ // TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
+ const Result result = npad->Activate(applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::DeactivateNpad(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ // This function does nothing since 10.0.0+
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ u64 unknown;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
+ parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
+
+ // Games expect this event to be signaled after calling this function
+ GetResourceManager()->GetNpad()->SignalStyleSetChangedEvent(parameters.npad_id);
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(
+ GetResourceManager()->GetNpad()->GetStyleSetChangedEvent(parameters.npad_id));
+}
+
+void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto controller = GetResourceManager()->GetNpad();
+ controller->DisconnectNpad(parameters.npad_id);
+
+ LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ Core::HID::LedPattern pattern{0, 0, 0, 0};
+ auto controller = GetResourceManager()->GetNpad();
+ const auto result = controller->GetLedPattern(npad_id, pattern);
+
+ LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result);
+ rb.Push(pattern.raw);
+}
+
+void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ NPad::NpadRevision revision;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
+ parameters.applet_resource_user_id);
+
+ auto npad = GetResourceManager()->GetNpad();
+
+ // TODO: npad->SetRevision(applet_resource_user_id, revision);
+ const auto result = npad->Activate(parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto hold_type{rp.PopEnum<NPad::NpadJoyHoldType>()};
+
+ GetResourceManager()->GetNpad()->SetHoldType(hold_type);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
+ applet_resource_user_id, hold_type);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(GetResourceManager()->GetNpad()->GetHoldType());
+}
+
+void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::NpadIdType new_npad_id{};
+ auto controller = GetResourceManager()->GetNpad();
+ controller->SetNpadMode(new_npad_id, parameters.npad_id, NPad::NpadJoyDeviceType::Left,
+ NPad::NpadJoyAssignmentMode::Single);
+
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ NPad::NpadJoyDeviceType npad_joy_device_type;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::NpadIdType new_npad_id{};
+ auto controller = GetResourceManager()->GetNpad();
+ controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
+ NPad::NpadJoyAssignmentMode::Single);
+
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
+ parameters.npad_id, parameters.applet_resource_user_id,
+ parameters.npad_joy_device_type);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::NpadIdType new_npad_id{};
+ auto controller = GetResourceManager()->GetNpad();
+ controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual);
+
+ LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id); // Spams a lot when controller applet is open
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
+ const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ auto controller = GetResourceManager()->GetNpad();
+ const auto result = controller->MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
+
+ LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
+ npad_id_1, npad_id_2, applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::StartLrAssignmentMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ GetResourceManager()->GetNpad()->StartLRAssignmentMode();
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ GetResourceManager()->GetNpad()->StopLRAssignmentMode();
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto activation_mode{rp.PopEnum<NPad::NpadHandheldActivationMode>()};
+
+ GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
+ applet_resource_user_id, activation_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadHandheldActivationMode());
+}
+
+void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
+ const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ auto controller = GetResourceManager()->GetNpad();
+ const auto result = controller->SwapNpadAssignment(npad_id_1, npad_id_2);
+
+ LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
+ npad_id_1, npad_id_2, applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ bool is_enabled = false;
+ auto controller = GetResourceManager()->GetNpad();
+ const auto result =
+ controller->IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
+ parameters.npad_id, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.Push(is_enabled);
+}
+
+void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool is_enabled;
+ INSERT_PADDING_BYTES_NOINIT(3);
+ Core::HID::NpadIdType npad_id;
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ auto controller = GetResourceManager()->GetNpad();
+ const auto result = controller->SetUnintendedHomeButtonInputProtectionEnabled(
+ parameters.is_enabled, parameters.npad_id);
+
+ LOG_DEBUG(Service_HID,
+ "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
+ parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ NPad::NpadJoyDeviceType npad_joy_device_type;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::NpadIdType new_npad_id{};
+ auto controller = GetResourceManager()->GetNpad();
+ const auto is_reassigned =
+ controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
+ NPad::NpadJoyAssignmentMode::Single);
+
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
+ parameters.npad_id, parameters.applet_resource_user_id,
+ parameters.npad_joy_device_type);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push(is_reassigned);
+ rb.PushEnum(new_npad_id);
+}
+
+void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool analog_stick_use_center_clamp;
+ INSERT_PADDING_BYTES_NOINIT(7);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ GetResourceManager()->GetNpad()->SetAnalogStickUseCenterClamp(
+ parameters.analog_stick_use_center_clamp);
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
+ parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadStyleSet npad_styleset;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ Core::HID::NpadButton button;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}",
+ parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
+ applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
+ const auto controller = GetResourceManager()->GetNpad();
+
+ Core::HID::VibrationDeviceInfo vibration_device_info;
+ bool check_device_index = false;
+
+ switch (vibration_device_handle.npad_type) {
+ case Core::HID::NpadStyleIndex::ProController:
+ case Core::HID::NpadStyleIndex::Handheld:
+ case Core::HID::NpadStyleIndex::JoyconDual:
+ case Core::HID::NpadStyleIndex::JoyconLeft:
+ case Core::HID::NpadStyleIndex::JoyconRight:
+ vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator;
+ check_device_index = true;
+ break;
+ case Core::HID::NpadStyleIndex::GameCube:
+ vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm;
+ break;
+ case Core::HID::NpadStyleIndex::N64:
+ vibration_device_info.type = Core::HID::VibrationDeviceType::N64;
+ break;
+ default:
+ vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown;
+ break;
+ }
+
+ vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
+ if (check_device_index) {
+ switch (vibration_device_handle.device_index) {
+ case Core::HID::DeviceIndex::Left:
+ vibration_device_info.position = Core::HID::VibrationDevicePosition::Left;
+ break;
+ case Core::HID::DeviceIndex::Right:
+ vibration_device_info.position = Core::HID::VibrationDevicePosition::Right;
+ break;
+ case Core::HID::DeviceIndex::None:
+ default:
+ ASSERT_MSG(false, "DeviceIndex should never be None!");
+ break;
+ }
+ }
+
+ LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
+ vibration_device_info.type, vibration_device_info.position);
+
+ const auto result = IsVibrationHandleValid(vibration_device_handle);
+ if (result.IsError()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(vibration_device_info);
+}
+
+void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::VibrationDeviceHandle vibration_device_handle;
+ Core::HID::VibrationValue vibration_value;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
+ parameters.vibration_value);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::VibrationDeviceHandle vibration_device_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 6};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(
+ GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle));
+}
+
+void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_HID, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(ResultSuccess);
+ rb.PushIpcInterface<IActiveVibrationDeviceList>(system, GetResourceManager());
+}
+
+void IHidServer::PermitVibration(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto can_vibrate{rp.Pop<bool>()};
+
+ // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value
+ // by converting it to a bool
+ Settings::values.vibration_enabled.SetValue(can_vibrate);
+
+ LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_HID, "called");
+
+ // nnSDK checks if a float is greater than zero. We return the bool we stored earlier
+ const auto is_enabled = Settings::values.vibration_enabled.GetValue();
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(is_enabled);
+}
+
+void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ const auto handle_data = ctx.ReadBuffer(0);
+ const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0);
+ const auto vibration_data = ctx.ReadBuffer(1);
+ const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1);
+
+ auto vibration_device_handles =
+ std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()),
+ handle_count);
+ auto vibration_values = std::span(
+ reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
+
+ GetResourceManager()->GetNpad()->VibrateControllers(vibration_device_handles, vibration_values);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::VibrationDeviceHandle vibration_device_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ Core::HID::VibrationGcErmCommand gc_erm_command;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ /**
+ * Note: This uses yuzu-specific behavior such that the StopHard command produces
+ * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below,
+ * in order to differentiate between Stop and StopHard commands.
+ * This is done to reuse the controller vibration functions made for regular controllers.
+ */
+ const auto vibration_value = [parameters] {
+ switch (parameters.gc_erm_command) {
+ case Core::HID::VibrationGcErmCommand::Stop:
+ return Core::HID::VibrationValue{
+ .low_amplitude = 0.0f,
+ .low_frequency = 160.0f,
+ .high_amplitude = 0.0f,
+ .high_frequency = 320.0f,
+ };
+ case Core::HID::VibrationGcErmCommand::Start:
+ return Core::HID::VibrationValue{
+ .low_amplitude = 1.0f,
+ .low_frequency = 160.0f,
+ .high_amplitude = 1.0f,
+ .high_frequency = 320.0f,
+ };
+ case Core::HID::VibrationGcErmCommand::StopHard:
+ return Core::HID::VibrationValue{
+ .low_amplitude = 0.0f,
+ .low_frequency = 0.0f,
+ .high_amplitude = 0.0f,
+ .high_frequency = 0.0f,
+ };
+ default:
+ return Core::HID::DEFAULT_VIBRATION_VALUE;
+ }
+ }();
+
+ GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
+ vibration_value);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
+ "gc_erm_command={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id,
+ parameters.gc_erm_command);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::VibrationDeviceHandle vibration_device_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ const auto last_vibration =
+ GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle);
+
+ const auto gc_erm_command = [last_vibration] {
+ if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
+ return Core::HID::VibrationGcErmCommand::Start;
+ }
+
+ /**
+ * Note: This uses yuzu-specific behavior such that the StopHard command produces
+ * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function
+ * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands.
+ * This is done to reuse the controller vibration functions made for regular controllers.
+ */
+ if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) {
+ return Core::HID::VibrationGcErmCommand::StopHard;
+ }
+
+ return Core::HID::VibrationGcErmCommand::Stop;
+ }();
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(gc_erm_command);
+}
+
+void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ GetResourceManager()->GetNpad()->SetPermitVibrationSession(true);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) {
+ GetResourceManager()->GetNpad()->SetPermitVibrationSession(false);
+
+ LOG_DEBUG(Service_HID, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::VibrationDeviceHandle vibration_device_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted(
+ parameters.vibration_device_handle));
+}
+
+void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ Result result = ResultSuccess;
+ auto console_sixaxis = GetResourceManager()->GetConsoleSixAxis();
+
+ if (!firmware_settings->IsDeviceManaged()) {
+ result = console_sixaxis->Activate();
+ }
+
+ if (result.IsSuccess()) {
+ result = console_sixaxis->Activate(applet_resource_user_id);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::StartConsoleSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
+ parameters.console_sixaxis_handle.unknown_1,
+ parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::StopConsoleSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
+ parameters.console_sixaxis_handle.unknown_1,
+ parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::ActivateSevenSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ Result result = ResultSuccess;
+ auto seven_sixaxis = GetResourceManager()->GetSevenSixAxis();
+
+ if (!firmware_settings->IsDeviceManaged()) {
+ result = seven_sixaxis->Activate();
+ }
+
+ if (result.IsSuccess()) {
+ seven_sixaxis->Activate(applet_resource_user_id);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::StartSevenSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
+ applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::StopSevenSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
+ applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto t_mem_1_size{rp.Pop<u64>()};
+ const auto t_mem_2_size{rp.Pop<u64>()};
+ const auto t_mem_1_handle{ctx.GetCopyHandle(0)};
+ const auto t_mem_2_handle{ctx.GetCopyHandle(1)};
+
+ ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes");
+ ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
+
+ auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
+ t_mem_1_handle);
+
+ if (t_mem_1.IsNull()) {
+ LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultUnknown);
+ return;
+ }
+
+ auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
+ t_mem_2_handle);
+
+ if (t_mem_2.IsNull()) {
+ LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultUnknown);
+ return;
+ }
+
+ ASSERT_MSG(t_mem_1->GetSize() == 0x1000, "t_mem_1 has incorrect size");
+ ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size");
+
+ // Activate console six axis controller
+ GetResourceManager()->GetConsoleSixAxis()->Activate();
+ GetResourceManager()->GetSevenSixAxis()->Activate();
+
+ GetResourceManager()->GetSevenSixAxis()->SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
+
+ LOG_WARNING(Service_HID,
+ "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
+ "applet_resource_user_id={}",
+ t_mem_1_handle, t_mem_2_handle, applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::FinalizeSevenSixAxisSensor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
+ applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ GetResourceManager()->GetSevenSixAxis()->ResetTimestamp();
+
+ LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(false);
+}
+
+void IHidServer::GetPalmaConnectionHandle(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
+ parameters.npad_id, parameters.applet_resource_user_id);
+
+ Palma::PalmaConnectionHandle handle;
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result = controller->GetPalmaConnectionHandle(parameters.npad_id, handle);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result);
+ rb.PushRaw(handle);
+}
+
+void IHidServer::InitializePalma(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result = controller->InitializePalma(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto controller = GetResourceManager()->GetPalma();
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(controller->AcquirePalmaOperationCompleteEvent(connection_handle));
+}
+
+void IHidServer::GetPalmaOperationInfo(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ Palma::PalmaOperationType operation_type;
+ Palma::PalmaOperationData data;
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result = controller->GetPalmaOperationInfo(connection_handle, operation_type, data);
+
+ if (result.IsError()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+ }
+
+ ctx.WriteBuffer(data);
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result);
+ rb.Push(static_cast<u64>(operation_type));
+}
+
+void IHidServer::PlayPalmaActivity(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+ const auto palma_activity{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}",
+ connection_handle.npad_id, palma_activity);
+
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result = controller->PlayPalmaActivity(connection_handle, palma_activity);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::SetPalmaFrModeType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+ const auto fr_mode{rp.PopEnum<Palma::PalmaFrModeType>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}",
+ connection_handle.npad_id, fr_mode);
+
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result = controller->SetPalmaFrModeType(connection_handle, fr_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ReadPalmaStep(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result = controller->ReadPalmaStep(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::EnablePalmaStep(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool is_enabled;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ Palma::PalmaConnectionHandle connection_handle;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}",
+ parameters.connection_handle.npad_id, parameters.is_enabled);
+
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result =
+ controller->EnablePalmaStep(parameters.connection_handle, parameters.is_enabled);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ResetPalmaStep(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto controller = GetResourceManager()->GetPalma();
+ const auto result = controller->ResetPalmaStep(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ReadPalmaApplicationSection(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::WritePalmaApplicationSection(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::ReadPalmaUniqueCode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ GetResourceManager()->GetPalma()->ReadPalmaUniqueCode(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ GetResourceManager()->GetPalma()->SetPalmaUniqueCodeInvalid(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::WritePalmaActivityEntry(HLERequestContext& ctx) {
+ LOG_CRITICAL(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+ const auto unknown{rp.Pop<u64>()};
+
+ [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
+ connection_handle.npad_id, unknown);
+
+ GetResourceManager()->GetPalma()->WritePalmaRgbLedPatternEntry(connection_handle, unknown);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::WritePalmaWaveEntry(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+ const auto wave_set{rp.PopEnum<Palma::PalmaWaveSet>()};
+ const auto unknown{rp.Pop<u64>()};
+ const auto t_mem_size{rp.Pop<u64>()};
+ const auto t_mem_handle{ctx.GetCopyHandle(0)};
+ const auto size{rp.Pop<u64>()};
+
+ ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
+
+ auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
+ t_mem_handle);
+
+ if (t_mem.IsNull()) {
+ LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultUnknown);
+ return;
+ }
+
+ ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
+ "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
+ connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
+
+ GetResourceManager()->GetPalma()->WritePalmaWaveEntry(connection_handle, wave_set,
+ t_mem->GetSourceAddress(), t_mem_size);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ s32 database_id_version;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ Palma::PalmaConnectionHandle connection_handle;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}",
+ parameters.connection_handle.npad_id, parameters.database_id_version);
+
+ GetResourceManager()->GetPalma()->SetPalmaDataBaseIdentificationVersion(
+ parameters.connection_handle, parameters.database_id_version);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ GetResourceManager()->GetPalma()->GetPalmaDataBaseIdentificationVersion(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SuspendPalmaFeature(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetPalmaOperationResult(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ const auto result =
+ GetResourceManager()->GetPalma()->GetPalmaOperationResult(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IHidServer::ReadPalmaPlayLog(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::ResetPalmaPlayLog(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetIsPalmaAllConnectable(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool is_palma_all_connectable;
+ INSERT_PADDING_BYTES_NOINIT(7);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}",
+ parameters.is_palma_all_connectable, parameters.applet_resource_user_id);
+
+ GetResourceManager()->GetPalma()->SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetIsPalmaPairedConnectable(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::PairPalma(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ GetResourceManager()->GetPalma()->PairPalma(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetPalmaBoostMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto palma_boost_mode{rp.Pop<bool>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode);
+
+ GetResourceManager()->GetPalma()->SetPalmaBoostMode(palma_boost_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::CancelWritePalmaWaveEntry(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::EnablePalmaBoostMode(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetPalmaBluetoothAddress(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto communication_mode{rp.PopEnum<NPad::NpadCommunicationMode>()};
+
+ GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode);
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
+ applet_resource_user_id, communication_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadCommunicationMode());
+}
+
+void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto touchscreen_mode{rp.PopRaw<Core::HID::TouchScreenConfigurationForNx>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, touchscreen_mode={}, applet_resource_user_id={}",
+ touchscreen_mode.mode, applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidServer::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ s32 unknown;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
+ parameters.unknown, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(false);
+}
+
+std::shared_ptr<ResourceManager> IHidServer::GetResourceManager() {
+ resource_manager->Initialize();
+ return resource_manager;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_server.h b/src/core/hle/service/hid/hid_server.h
new file mode 100644
index 000000000..eb2e8e7f4
--- /dev/null
+++ b/src/core/hle/service/hid/hid_server.h
@@ -0,0 +1,149 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Core {
+class System;
+}
+
+namespace Service::HID {
+class ResourceManager;
+class HidFirmwareSettings;
+
+class IHidServer final : public ServiceFramework<IHidServer> {
+public:
+ explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource,
+ std::shared_ptr<HidFirmwareSettings> settings);
+ ~IHidServer() override;
+
+ std::shared_ptr<ResourceManager> GetResourceManager();
+
+private:
+ void CreateAppletResource(HLERequestContext& ctx);
+ void ActivateDebugPad(HLERequestContext& ctx);
+ void ActivateTouchScreen(HLERequestContext& ctx);
+ void ActivateMouse(HLERequestContext& ctx);
+ void ActivateKeyboard(HLERequestContext& ctx);
+ void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
+ void AcquireXpadIdEventHandle(HLERequestContext& ctx);
+ void ReleaseXpadIdEventHandle(HLERequestContext& ctx);
+ void ActivateXpad(HLERequestContext& ctx);
+ void GetXpadIds(HLERequestContext& ctx);
+ void ActivateJoyXpad(HLERequestContext& ctx);
+ void GetJoyXpadLifoHandle(HLERequestContext& ctx);
+ void GetJoyXpadIds(HLERequestContext& ctx);
+ void ActivateSixAxisSensor(HLERequestContext& ctx);
+ void DeactivateSixAxisSensor(HLERequestContext& ctx);
+ void GetSixAxisSensorLifoHandle(HLERequestContext& ctx);
+ void ActivateJoySixAxisSensor(HLERequestContext& ctx);
+ void DeactivateJoySixAxisSensor(HLERequestContext& ctx);
+ void GetJoySixAxisSensorLifoHandle(HLERequestContext& ctx);
+ void StartSixAxisSensor(HLERequestContext& ctx);
+ void StopSixAxisSensor(HLERequestContext& ctx);
+ void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
+ void EnableSixAxisSensorFusion(HLERequestContext& ctx);
+ void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
+ void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
+ void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
+ void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
+ void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
+ void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
+ void IsSixAxisSensorAtRest(HLERequestContext& ctx);
+ void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
+ void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
+ void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
+ void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
+ void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
+ void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
+ void ActivateGesture(HLERequestContext& ctx);
+ void SetSupportedNpadStyleSet(HLERequestContext& ctx);
+ void GetSupportedNpadStyleSet(HLERequestContext& ctx);
+ void SetSupportedNpadIdType(HLERequestContext& ctx);
+ void ActivateNpad(HLERequestContext& ctx);
+ void DeactivateNpad(HLERequestContext& ctx);
+ void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
+ void DisconnectNpad(HLERequestContext& ctx);
+ void GetPlayerLedPattern(HLERequestContext& ctx);
+ void ActivateNpadWithRevision(HLERequestContext& ctx);
+ void SetNpadJoyHoldType(HLERequestContext& ctx);
+ void GetNpadJoyHoldType(HLERequestContext& ctx);
+ void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
+ void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
+ void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
+ void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
+ void StartLrAssignmentMode(HLERequestContext& ctx);
+ void StopLrAssignmentMode(HLERequestContext& ctx);
+ void SetNpadHandheldActivationMode(HLERequestContext& ctx);
+ void GetNpadHandheldActivationMode(HLERequestContext& ctx);
+ void SwapNpadAssignment(HLERequestContext& ctx);
+ void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
+ void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
+ void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
+ void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
+ void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
+ void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
+ void GetVibrationDeviceInfo(HLERequestContext& ctx);
+ void SendVibrationValue(HLERequestContext& ctx);
+ void GetActualVibrationValue(HLERequestContext& ctx);
+ void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
+ void PermitVibration(HLERequestContext& ctx);
+ void IsVibrationPermitted(HLERequestContext& ctx);
+ void SendVibrationValues(HLERequestContext& ctx);
+ void SendVibrationGcErmCommand(HLERequestContext& ctx);
+ void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
+ void BeginPermitVibrationSession(HLERequestContext& ctx);
+ void EndPermitVibrationSession(HLERequestContext& ctx);
+ void IsVibrationDeviceMounted(HLERequestContext& ctx);
+ void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
+ void StartConsoleSixAxisSensor(HLERequestContext& ctx);
+ void StopConsoleSixAxisSensor(HLERequestContext& ctx);
+ void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
+ void StartSevenSixAxisSensor(HLERequestContext& ctx);
+ void StopSevenSixAxisSensor(HLERequestContext& ctx);
+ void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
+ void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
+ void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
+ void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
+ void GetPalmaConnectionHandle(HLERequestContext& ctx);
+ void InitializePalma(HLERequestContext& ctx);
+ void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
+ void GetPalmaOperationInfo(HLERequestContext& ctx);
+ void PlayPalmaActivity(HLERequestContext& ctx);
+ void SetPalmaFrModeType(HLERequestContext& ctx);
+ void ReadPalmaStep(HLERequestContext& ctx);
+ void EnablePalmaStep(HLERequestContext& ctx);
+ void ResetPalmaStep(HLERequestContext& ctx);
+ void ReadPalmaApplicationSection(HLERequestContext& ctx);
+ void WritePalmaApplicationSection(HLERequestContext& ctx);
+ void ReadPalmaUniqueCode(HLERequestContext& ctx);
+ void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
+ void WritePalmaActivityEntry(HLERequestContext& ctx);
+ void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
+ void WritePalmaWaveEntry(HLERequestContext& ctx);
+ void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
+ void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
+ void SuspendPalmaFeature(HLERequestContext& ctx);
+ void GetPalmaOperationResult(HLERequestContext& ctx);
+ void ReadPalmaPlayLog(HLERequestContext& ctx);
+ void ResetPalmaPlayLog(HLERequestContext& ctx);
+ void SetIsPalmaAllConnectable(HLERequestContext& ctx);
+ void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
+ void PairPalma(HLERequestContext& ctx);
+ void SetPalmaBoostMode(HLERequestContext& ctx);
+ void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
+ void EnablePalmaBoostMode(HLERequestContext& ctx);
+ void GetPalmaBluetoothAddress(HLERequestContext& ctx);
+ void SetDisallowedPalmaConnection(HLERequestContext& ctx);
+ void SetNpadCommunicationMode(HLERequestContext& ctx);
+ void GetNpadCommunicationMode(HLERequestContext& ctx);
+ void SetTouchScreenConfiguration(HLERequestContext& ctx);
+ void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
+
+ std::shared_ptr<ResourceManager> resource_manager;
+ std::shared_ptr<HidFirmwareSettings> firmware_settings;
+};
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
new file mode 100644
index 000000000..b56d0347a
--- /dev/null
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -0,0 +1,539 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/controllers/npad.h"
+#include "core/hle/service/hid/controllers/touchscreen.h"
+#include "core/hle/service/hid/errors.h"
+#include "core/hle/service/hid/hid_system_server.h"
+#include "core/hle/service/hid/resource_manager.h"
+#include "core/hle/service/ipc_helpers.h"
+
+namespace Service::HID {
+
+IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
+ : ServiceFramework{system_, "hid:sys"}, service_context{system_, service_name},
+ resource_manager{resource} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {31, nullptr, "SendKeyboardLockKeyEvent"},
+ {101, nullptr, "AcquireHomeButtonEventHandle"},
+ {111, nullptr, "ActivateHomeButton"},
+ {121, nullptr, "AcquireSleepButtonEventHandle"},
+ {131, nullptr, "ActivateSleepButton"},
+ {141, nullptr, "AcquireCaptureButtonEventHandle"},
+ {151, nullptr, "ActivateCaptureButton"},
+ {161, nullptr, "GetPlatformConfig"},
+ {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
+ {211, nullptr, "GetNpadsWithNfc"},
+ {212, nullptr, "AcquireNfcActivateEventHandle"},
+ {213, nullptr, "ActivateNfc"},
+ {214, nullptr, "GetXcdHandleForNpadWithNfc"},
+ {215, nullptr, "IsNfcActivated"},
+ {230, nullptr, "AcquireIrSensorEventHandle"},
+ {231, nullptr, "ActivateIrSensor"},
+ {232, nullptr, "GetIrSensorState"},
+ {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
+ {301, nullptr, "ActivateNpadSystem"},
+ {303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
+ {304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"},
+ {305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"},
+ {306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"},
+ {307, nullptr, "GetNpadSystemExtStyle"},
+ {308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"},
+ {309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"},
+ {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"},
+ {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
+ {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"},
+ {313, nullptr, "GetNpadCaptureButtonAssignment"},
+ {314, nullptr, "GetAppletFooterUiType"},
+ {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"},
+ {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"},
+ {317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"},
+ {318, &IHidSystemServer::HasBattery, "HasBattery"},
+ {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"},
+ {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
+ {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"},
+ {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
+ {324, nullptr, "GetUniquePadButtonSet"},
+ {325, nullptr, "GetUniquePadColor"},
+ {326, nullptr, "GetUniquePadAppletDetailedUiType"},
+ {327, nullptr, "GetAbstractedPadIdDataFromNpad"},
+ {328, nullptr, "AttachAbstractedPadToNpad"},
+ {329, nullptr, "DetachAbstractedPadAll"},
+ {330, nullptr, "CheckAbstractedPadConnection"},
+ {500, nullptr, "SetAppletResourceUserId"},
+ {501, nullptr, "RegisterAppletResourceUserId"},
+ {502, nullptr, "UnregisterAppletResourceUserId"},
+ {503, nullptr, "EnableAppletToGetInput"},
+ {504, nullptr, "SetAruidValidForVibration"},
+ {505, nullptr, "EnableAppletToGetSixAxisSensor"},
+ {506, nullptr, "EnableAppletToGetPadInput"},
+ {507, nullptr, "EnableAppletToGetTouchScreen"},
+ {510, nullptr, "SetVibrationMasterVolume"},
+ {511, nullptr, "GetVibrationMasterVolume"},
+ {512, nullptr, "BeginPermitVibrationSession"},
+ {513, nullptr, "EndPermitVibrationSession"},
+ {514, nullptr, "Unknown514"},
+ {520, nullptr, "EnableHandheldHids"},
+ {521, nullptr, "DisableHandheldHids"},
+ {522, nullptr, "SetJoyConRailEnabled"},
+ {523, nullptr, "IsJoyConRailEnabled"},
+ {524, nullptr, "IsHandheldHidsEnabled"},
+ {525, nullptr, "IsJoyConAttachedOnAllRail"},
+ {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
+ {541, nullptr, "GetPlayReportControllerUsages"},
+ {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
+ {543, nullptr, "GetRegisteredDevicesOld"},
+ {544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"},
+ {545, nullptr, "SendConnectionTrigger"},
+ {546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"},
+ {547, nullptr, "GetAllowedBluetoothLinksCount"},
+ {548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"},
+ {549, nullptr, "GetConnectableRegisteredDevices"},
+ {700, nullptr, "ActivateUniquePad"},
+ {702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"},
+ {703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"},
+ {751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
+ {800, nullptr, "ListSixAxisSensorHandles"},
+ {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
+ {802, nullptr, "ResetSixAxisSensorCalibrationValues"},
+ {803, nullptr, "StartSixAxisSensorUserCalibration"},
+ {804, nullptr, "CancelSixAxisSensorUserCalibration"},
+ {805, nullptr, "GetUniquePadBluetoothAddress"},
+ {806, nullptr, "DisconnectUniquePad"},
+ {807, nullptr, "GetUniquePadType"},
+ {808, nullptr, "GetUniquePadInterface"},
+ {809, nullptr, "GetUniquePadSerialNumber"},
+ {810, nullptr, "GetUniquePadControllerNumber"},
+ {811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
+ {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
+ {821, nullptr, "StartAnalogStickManualCalibration"},
+ {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
+ {823, nullptr, "CancelAnalogStickManualCalibration"},
+ {824, nullptr, "ResetAnalogStickManualCalibration"},
+ {825, nullptr, "GetAnalogStickState"},
+ {826, nullptr, "GetAnalogStickManualCalibrationStage"},
+ {827, nullptr, "IsAnalogStickButtonPressed"},
+ {828, nullptr, "IsAnalogStickInReleasePosition"},
+ {829, nullptr, "IsAnalogStickInCircumference"},
+ {830, nullptr, "SetNotificationLedPattern"},
+ {831, nullptr, "SetNotificationLedPatternWithTimeout"},
+ {832, nullptr, "PrepareHidsForNotificationWake"},
+ {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
+ {851, nullptr, "EnableUsbFullKeyController"},
+ {852, nullptr, "IsUsbConnected"},
+ {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"},
+ {900, nullptr, "ActivateInputDetector"},
+ {901, nullptr, "NotifyInputDetector"},
+ {1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"},
+ {1001, nullptr, "GetFirmwareVersion"},
+ {1002, nullptr, "GetAvailableFirmwareVersion"},
+ {1003, nullptr, "IsFirmwareUpdateAvailable"},
+ {1004, nullptr, "CheckFirmwareUpdateRequired"},
+ {1005, nullptr, "StartFirmwareUpdate"},
+ {1006, nullptr, "AbortFirmwareUpdate"},
+ {1007, nullptr, "GetFirmwareUpdateState"},
+ {1008, nullptr, "ActivateAudioControl"},
+ {1009, nullptr, "AcquireAudioControlEventHandle"},
+ {1010, nullptr, "GetAudioControlStates"},
+ {1011, nullptr, "DeactivateAudioControl"},
+ {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
+ {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
+ {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
+ {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
+ {1100, nullptr, "GetHidbusSystemServiceObject"},
+ {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
+ {1130, nullptr, "InitializeUsbFirmwareUpdate"},
+ {1131, nullptr, "FinalizeUsbFirmwareUpdate"},
+ {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
+ {1133, nullptr, "StartUsbFirmwareUpdate"},
+ {1134, nullptr, "GetUsbFirmwareUpdateState"},
+ {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"},
+ {1150, nullptr, "SetTouchScreenMagnification"},
+ {1151, nullptr, "GetTouchScreenFirmwareVersion"},
+ {1152, nullptr, "SetTouchScreenDefaultConfiguration"},
+ {1153, &IHidSystemServer::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"},
+ {1154, nullptr, "IsFirmwareAvailableForNotification"},
+ {1155, nullptr, "SetForceHandheldStyleVibration"},
+ {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
+ {1157, nullptr, "CancelConnectionTrigger"},
+ {1200, nullptr, "IsButtonConfigSupported"},
+ {1201, nullptr, "IsButtonConfigEmbeddedSupported"},
+ {1202, nullptr, "DeleteButtonConfig"},
+ {1203, nullptr, "DeleteButtonConfigEmbedded"},
+ {1204, nullptr, "SetButtonConfigEnabled"},
+ {1205, nullptr, "SetButtonConfigEmbeddedEnabled"},
+ {1206, nullptr, "IsButtonConfigEnabled"},
+ {1207, nullptr, "IsButtonConfigEmbeddedEnabled"},
+ {1208, nullptr, "SetButtonConfigEmbedded"},
+ {1209, nullptr, "SetButtonConfigFull"},
+ {1210, nullptr, "SetButtonConfigLeft"},
+ {1211, nullptr, "SetButtonConfigRight"},
+ {1212, nullptr, "GetButtonConfigEmbedded"},
+ {1213, nullptr, "GetButtonConfigFull"},
+ {1214, nullptr, "GetButtonConfigLeft"},
+ {1215, nullptr, "GetButtonConfigRight"},
+ {1250, nullptr, "IsCustomButtonConfigSupported"},
+ {1251, nullptr, "IsDefaultButtonConfigEmbedded"},
+ {1252, nullptr, "IsDefaultButtonConfigFull"},
+ {1253, nullptr, "IsDefaultButtonConfigLeft"},
+ {1254, nullptr, "IsDefaultButtonConfigRight"},
+ {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"},
+ {1256, nullptr, "IsButtonConfigStorageFullEmpty"},
+ {1257, nullptr, "IsButtonConfigStorageLeftEmpty"},
+ {1258, nullptr, "IsButtonConfigStorageRightEmpty"},
+ {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"},
+ {1260, nullptr, "GetButtonConfigStorageFullDeprecated"},
+ {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"},
+ {1262, nullptr, "GetButtonConfigStorageRightDeprecated"},
+ {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"},
+ {1264, nullptr, "SetButtonConfigStorageFullDeprecated"},
+ {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"},
+ {1266, nullptr, "SetButtonConfigStorageRightDeprecated"},
+ {1267, nullptr, "DeleteButtonConfigStorageEmbedded"},
+ {1268, nullptr, "DeleteButtonConfigStorageFull"},
+ {1269, nullptr, "DeleteButtonConfigStorageLeft"},
+ {1270, nullptr, "DeleteButtonConfigStorageRight"},
+ {1271, nullptr, "IsUsingCustomButtonConfig"},
+ {1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
+ {1273, nullptr, "SetAllCustomButtonConfigEnabled"},
+ {1274, nullptr, "SetDefaultButtonConfig"},
+ {1275, nullptr, "SetAllDefaultButtonConfig"},
+ {1276, nullptr, "SetHidButtonConfigEmbedded"},
+ {1277, nullptr, "SetHidButtonConfigFull"},
+ {1278, nullptr, "SetHidButtonConfigLeft"},
+ {1279, nullptr, "SetHidButtonConfigRight"},
+ {1280, nullptr, "GetHidButtonConfigEmbedded"},
+ {1281, nullptr, "GetHidButtonConfigFull"},
+ {1282, nullptr, "GetHidButtonConfigLeft"},
+ {1283, nullptr, "GetHidButtonConfigRight"},
+ {1284, nullptr, "GetButtonConfigStorageEmbedded"},
+ {1285, nullptr, "GetButtonConfigStorageFull"},
+ {1286, nullptr, "GetButtonConfigStorageLeft"},
+ {1287, nullptr, "GetButtonConfigStorageRight"},
+ {1288, nullptr, "SetButtonConfigStorageEmbedded"},
+ {1289, nullptr, "SetButtonConfigStorageFull"},
+ {1290, nullptr, "DeleteButtonConfigStorageRight"},
+ {1291, nullptr, "DeleteButtonConfigStorageRight"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+
+ joy_detach_event = service_context.CreateEvent("IHidSystemServer::JoyDetachEvent");
+ acquire_device_registered_event =
+ service_context.CreateEvent("IHidSystemServer::AcquireDeviceRegisteredEvent");
+ acquire_connection_trigger_timeout_event =
+ service_context.CreateEvent("IHidSystemServer::AcquireConnectionTriggerTimeoutEvent");
+ unique_pad_connection_event =
+ service_context.CreateEvent("IHidSystemServer::AcquireUniquePadConnectionEventHandle");
+}
+
+IHidSystemServer::~IHidSystemServer() {
+ service_context.CloseEvent(joy_detach_event);
+ service_context.CloseEvent(acquire_device_registered_event);
+ service_context.CloseEvent(acquire_connection_trigger_timeout_event);
+ service_context.CloseEvent(unique_pad_connection_event);
+};
+
+void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "called");
+
+ GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_HID, "(STUBBED) called"); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(system.HIDCore().GetLastActiveController());
+}
+
+void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "called");
+
+ GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ Core::HID::NpadColor left_color{};
+ Core::HID::NpadColor right_color{};
+ // TODO: Get colors from Npad
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(left_color);
+ rb.PushRaw(right_color);
+}
+
+void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_INFO(Service_HID, "(STUBBED) called");
+
+ Core::HID::NpadStyleSet supported_styleset =
+ GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(supported_styleset);
+}
+
+void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_INFO(Service_HID, "(STUBBED) called");
+
+ Core::HID::NpadStyleSet supported_styleset =
+ GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(supported_styleset);
+}
+
+void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ const NPad::AppletDetailedUiType detailed_ui_type =
+ GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(detailed_ui_type);
+}
+
+void IHidSystemServer::GetNpadInterfaceType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
+}
+
+void IHidSystemServer::GetNpadLeftRightInterfaceType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
+ rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
+}
+
+void IHidSystemServer::HasBattery(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(false);
+}
+
+void IHidSystemServer::HasLeftRightBattery(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ struct LeftRightBattery {
+ bool left;
+ bool right;
+ };
+
+ LeftRightBattery left_right_battery{
+ .left = false,
+ .right = false,
+ };
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(left_right_battery);
+}
+
+void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ const std::vector<Core::HID::UniquePadId> unique_pads{};
+
+ if (!unique_pads.empty()) {
+ ctx.WriteBuffer(unique_pads);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(static_cast<u32>(unique_pads.size()));
+}
+
+void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
+ LOG_INFO(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
+}
+
+void IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx) {
+ LOG_INFO(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
+}
+
+void IHidSystemServer::GetRegisteredDevices(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ struct RegisterData {
+ std::array<u8, 0x68> data;
+ };
+ static_assert(sizeof(RegisterData) == 0x68, "RegisterData is an invalid size");
+ std::vector<RegisterData> registered_devices{};
+
+ if (!registered_devices.empty()) {
+ ctx.WriteBuffer(registered_devices);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u64>(registered_devices.size());
+}
+
+void IHidSystemServer::AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.PushCopyObjects(unique_pad_connection_event->GetReadableEvent());
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::GetUniquePadIds(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u64>(0);
+}
+
+void IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) {
+ LOG_INFO(Service_AM, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(joy_detach_event->GetReadableEvent());
+}
+
+void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
+ const bool is_enabled = false;
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(is_enabled);
+}
+
+void IHidSystemServer::IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx) {
+ const bool button_pressed = false;
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}",
+ button_pressed); // Spams a lot when controller applet is open
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(button_pressed);
+}
+
+void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ Core::HID::TouchScreenConfigurationForNx touchscreen_config{
+ .mode = Core::HID::TouchScreenModeForNx::Finger,
+ };
+
+ if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 &&
+ touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) {
+ touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 6};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(touchscreen_config);
+}
+
+std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() {
+ resource_manager->Initialize();
+ return resource_manager;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
new file mode 100644
index 000000000..822d5e5b9
--- /dev/null
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -0,0 +1,63 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/service.h"
+
+namespace Core {
+class System;
+}
+
+namespace Kernel {
+class KEvent;
+}
+
+namespace Service::HID {
+class ResourceManager;
+
+class IHidSystemServer final : public ServiceFramework<IHidSystemServer> {
+public:
+ explicit IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
+ ~IHidSystemServer() override;
+
+private:
+ void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx);
+ void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
+ void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
+ void GetLastActiveNpad(HLERequestContext& ctx);
+ void ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx);
+ void GetNpadFullKeyGripColor(HLERequestContext& ctx);
+ void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx);
+ void SetSupportedNpadStyleSetAll(HLERequestContext& ctx);
+ void GetAppletDetailedUiType(HLERequestContext& ctx);
+ void GetNpadInterfaceType(HLERequestContext& ctx);
+ void GetNpadLeftRightInterfaceType(HLERequestContext& ctx);
+ void HasBattery(HLERequestContext& ctx);
+ void HasLeftRightBattery(HLERequestContext& ctx);
+ void GetUniquePadsFromNpad(HLERequestContext& ctx);
+ void GetIrSensorState(HLERequestContext& ctx);
+ void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
+ void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
+ void GetRegisteredDevices(HLERequestContext& ctx);
+ void AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx);
+ void GetUniquePadIds(HLERequestContext& ctx);
+ void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx);
+ void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
+ void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx);
+ void InitializeFirmwareUpdate(HLERequestContext& ctx);
+ void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx);
+ void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
+
+ std::shared_ptr<ResourceManager> GetResourceManager();
+
+ Kernel::KEvent* acquire_connection_trigger_timeout_event;
+ Kernel::KEvent* acquire_device_registered_event;
+ Kernel::KEvent* joy_detach_event;
+ Kernel::KEvent* unique_pad_connection_event;
+ KernelHelpers::ServiceContext service_context;
+ std::shared_ptr<ResourceManager> resource_manager;
+};
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_util.h b/src/core/hle/service/hid/hid_util.h
new file mode 100644
index 000000000..b87cc10e3
--- /dev/null
+++ b/src/core/hle/service/hid/hid_util.h
@@ -0,0 +1,146 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "core/hid/hid_types.h"
+#include "core/hle/service/hid/errors.h"
+
+namespace Service::HID {
+
+constexpr bool IsNpadIdValid(const Core::HID::NpadIdType npad_id) {
+ switch (npad_id) {
+ case Core::HID::NpadIdType::Player1:
+ case Core::HID::NpadIdType::Player2:
+ case Core::HID::NpadIdType::Player3:
+ case Core::HID::NpadIdType::Player4:
+ case Core::HID::NpadIdType::Player5:
+ case Core::HID::NpadIdType::Player6:
+ case Core::HID::NpadIdType::Player7:
+ case Core::HID::NpadIdType::Player8:
+ case Core::HID::NpadIdType::Other:
+ case Core::HID::NpadIdType::Handheld:
+ return true;
+ default:
+ return false;
+ }
+}
+
+constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& handle) {
+ const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id));
+ const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
+
+ if (!npad_id) {
+ return InvalidNpadId;
+ }
+ if (!device_index) {
+ return NpadDeviceIndexOutOfRange;
+ }
+
+ return ResultSuccess;
+}
+
+constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) {
+ switch (handle.npad_type) {
+ case Core::HID::NpadStyleIndex::ProController:
+ case Core::HID::NpadStyleIndex::Handheld:
+ case Core::HID::NpadStyleIndex::JoyconDual:
+ case Core::HID::NpadStyleIndex::JoyconLeft:
+ case Core::HID::NpadStyleIndex::JoyconRight:
+ case Core::HID::NpadStyleIndex::GameCube:
+ case Core::HID::NpadStyleIndex::N64:
+ case Core::HID::NpadStyleIndex::SystemExt:
+ case Core::HID::NpadStyleIndex::System:
+ // These support vibration
+ break;
+ default:
+ return VibrationInvalidStyleIndex;
+ }
+
+ if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) {
+ return VibrationInvalidNpadId;
+ }
+
+ if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) {
+ return VibrationDeviceIndexOutOfRange;
+ }
+
+ return ResultSuccess;
+}
+
+/// Converts a Core::HID::NpadIdType to an array index.
+constexpr size_t NpadIdTypeToIndex(Core::HID::NpadIdType npad_id_type) {
+ switch (npad_id_type) {
+ case Core::HID::NpadIdType::Player1:
+ return 0;
+ case Core::HID::NpadIdType::Player2:
+ return 1;
+ case Core::HID::NpadIdType::Player3:
+ return 2;
+ case Core::HID::NpadIdType::Player4:
+ return 3;
+ case Core::HID::NpadIdType::Player5:
+ return 4;
+ case Core::HID::NpadIdType::Player6:
+ return 5;
+ case Core::HID::NpadIdType::Player7:
+ return 6;
+ case Core::HID::NpadIdType::Player8:
+ return 7;
+ case Core::HID::NpadIdType::Handheld:
+ return 8;
+ case Core::HID::NpadIdType::Other:
+ return 9;
+ default:
+ return 8;
+ }
+}
+
+/// Converts an array index to a Core::HID::NpadIdType
+constexpr Core::HID::NpadIdType IndexToNpadIdType(size_t index) {
+ switch (index) {
+ case 0:
+ return Core::HID::NpadIdType::Player1;
+ case 1:
+ return Core::HID::NpadIdType::Player2;
+ case 2:
+ return Core::HID::NpadIdType::Player3;
+ case 3:
+ return Core::HID::NpadIdType::Player4;
+ case 4:
+ return Core::HID::NpadIdType::Player5;
+ case 5:
+ return Core::HID::NpadIdType::Player6;
+ case 6:
+ return Core::HID::NpadIdType::Player7;
+ case 7:
+ return Core::HID::NpadIdType::Player8;
+ case 8:
+ return Core::HID::NpadIdType::Handheld;
+ case 9:
+ return Core::HID::NpadIdType::Other;
+ default:
+ return Core::HID::NpadIdType::Invalid;
+ }
+}
+
+constexpr Core::HID::NpadStyleSet GetStylesetByIndex(std::size_t index) {
+ switch (index) {
+ case 0:
+ return Core::HID::NpadStyleSet::Fullkey;
+ case 1:
+ return Core::HID::NpadStyleSet::Handheld;
+ case 2:
+ return Core::HID::NpadStyleSet::JoyDual;
+ case 3:
+ return Core::HID::NpadStyleSet::JoyLeft;
+ case 4:
+ return Core::HID::NpadStyleSet::JoyRight;
+ case 5:
+ return Core::HID::NpadStyleSet::Palma;
+ default:
+ return Core::HID::NpadStyleSet::None;
+ }
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 221c33b86..39b9a4474 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -12,6 +12,7 @@
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/hid/errors.h"
+#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/hid/irs.h"
#include "core/hle/service/hid/irsensor/clustering_processor.h"
#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
@@ -138,7 +139,7 @@ void IRS::RunMomentProcessor(HLERequestContext& ctx) {
if (result.IsSuccess()) {
auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
- MakeProcessor<MomentProcessor>(parameters.camera_handle, device);
+ MakeProcessorWithCoreContext<MomentProcessor>(parameters.camera_handle, device);
auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle);
image_transfer_processor.SetConfig(parameters.processor_config);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
@@ -320,7 +321,7 @@ void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) {
}
Core::IrSensor::IrCameraHandle camera_handle{
- .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)),
+ .npad_id = static_cast<u8>(HID::NpadIdTypeToIndex(npad_id)),
.npad_type = Core::HID::NpadStyleIndex::None,
};
@@ -545,7 +546,7 @@ void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) {
Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
if (camera_handle.npad_id >
- static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
+ static_cast<u8>(HID::NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
return InvalidIrCameraHandle;
}
if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) {
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index a8fa19025..c8e6dab17 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -3,15 +3,12 @@
#pragma once
+#include "core/core.h"
#include "core/hid/hid_types.h"
#include "core/hid/irs_types.h"
#include "core/hle/service/hid/irsensor/processor_base.h"
#include "core/hle/service/service.h"
-namespace Core {
-class System;
-}
-
namespace Core::HID {
class EmulatedController;
} // namespace Core::HID
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.cpp b/src/core/hle/service/hid/irsensor/clustering_processor.cpp
index e2f4ae876..c559eb0d5 100644
--- a/src/core/hle/service/hid/irsensor/clustering_processor.cpp
+++ b/src/core/hle/service/hid/irsensor/clustering_processor.cpp
@@ -3,16 +3,18 @@
#include <queue>
+#include "core/core.h"
+#include "core/core_timing.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/irsensor/clustering_processor.h"
namespace Service::IRS {
-ClusteringProcessor::ClusteringProcessor(Core::HID::HIDCore& hid_core_,
+ClusteringProcessor::ClusteringProcessor(Core::System& system_,
Core::IrSensor::DeviceFormat& device_format,
std::size_t npad_index)
- : device{device_format} {
- npad_device = hid_core_.GetEmulatedControllerByIndex(npad_index);
+ : device{device_format}, system{system_} {
+ npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
device.mode = Core::IrSensor::IrSensorMode::ClusteringProcessor;
device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
@@ -48,7 +50,7 @@ void ClusteringProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType ty
}
next_state = {};
- const auto camera_data = npad_device->GetCamera();
+ const auto& camera_data = npad_device->GetCamera();
auto filtered_image = camera_data.data;
RemoveLowIntensityData(filtered_image);
@@ -83,7 +85,7 @@ void ClusteringProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType ty
}
next_state.sampling_number = camera_data.sample;
- next_state.timestamp = next_state.timestamp + 131;
+ next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count();
next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
shared_memory->clustering_lifo.WriteNextEntry(next_state);
@@ -202,14 +204,14 @@ ClusteringProcessor::ClusteringData ClusteringProcessor::MergeCluster(
}
u8 ClusteringProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const {
- if ((y * width) + x > data.size()) {
+ if ((y * width) + x >= data.size()) {
return 0;
}
return data[(y * width) + x];
}
void ClusteringProcessor::SetPixel(std::vector<u8>& data, std::size_t x, std::size_t y, u8 value) {
- if ((y * width) + x > data.size()) {
+ if ((y * width) + x >= data.size()) {
return;
}
data[(y * width) + x] = value;
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.h b/src/core/hle/service/hid/irsensor/clustering_processor.h
index dc01a8ea7..83f34734a 100644
--- a/src/core/hle/service/hid/irsensor/clustering_processor.h
+++ b/src/core/hle/service/hid/irsensor/clustering_processor.h
@@ -8,6 +8,10 @@
#include "core/hle/service/hid/irs_ring_lifo.h"
#include "core/hle/service/hid/irsensor/processor_base.h"
+namespace Core {
+class System;
+}
+
namespace Core::HID {
class EmulatedController;
} // namespace Core::HID
@@ -15,8 +19,7 @@ class EmulatedController;
namespace Service::IRS {
class ClusteringProcessor final : public ProcessorBase {
public:
- explicit ClusteringProcessor(Core::HID::HIDCore& hid_core_,
- Core::IrSensor::DeviceFormat& device_format,
+ explicit ClusteringProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
std::size_t npad_index);
~ClusteringProcessor() override;
@@ -106,5 +109,7 @@ private:
Core::IrSensor::DeviceFormat& device;
Core::HID::EmulatedController* npad_device;
int callback_key{};
+
+ Core::System& system;
};
} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
index 803a6277c..22067a591 100644
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
+++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
@@ -49,7 +49,7 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
return;
}
- const auto camera_data = npad_device->GetCamera();
+ const auto& camera_data = npad_device->GetCamera();
// This indicates how much ambient light is present
processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.cpp b/src/core/hle/service/hid/irsensor/moment_processor.cpp
index dbaca420a..cf045bda7 100644
--- a/src/core/hle/service/hid/irsensor/moment_processor.cpp
+++ b/src/core/hle/service/hid/irsensor/moment_processor.cpp
@@ -1,24 +1,137 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "core/core.h"
+#include "core/core_timing.h"
+#include "core/hid/emulated_controller.h"
+#include "core/hid/hid_core.h"
#include "core/hle/service/hid/irsensor/moment_processor.h"
namespace Service::IRS {
-MomentProcessor::MomentProcessor(Core::IrSensor::DeviceFormat& device_format)
- : device(device_format) {
+static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size40x30;
+static constexpr std::size_t ImageWidth = 40;
+static constexpr std::size_t ImageHeight = 30;
+
+MomentProcessor::MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
+ std::size_t npad_index)
+ : device(device_format), system{system_} {
+ npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
+
device.mode = Core::IrSensor::IrSensorMode::MomentProcessor;
device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
+
+ shared_memory = std::construct_at(
+ reinterpret_cast<MomentSharedMemory*>(&device_format.state.processor_raw_data));
+
+ Core::HID::ControllerUpdateCallback engine_callback{
+ .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); },
+ .is_npad_service = true,
+ };
+ callback_key = npad_device->SetCallback(engine_callback);
}
-MomentProcessor::~MomentProcessor() = default;
+MomentProcessor::~MomentProcessor() {
+ npad_device->DeleteCallback(callback_key);
+};
-void MomentProcessor::StartProcessor() {}
+void MomentProcessor::StartProcessor() {
+ device.camera_status = Core::IrSensor::IrCameraStatus::Available;
+ device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready;
+}
void MomentProcessor::SuspendProcessor() {}
void MomentProcessor::StopProcessor() {}
+void MomentProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) {
+ if (type != Core::HID::ControllerTriggerType::IrSensor) {
+ return;
+ }
+
+ next_state = {};
+ const auto& camera_data = npad_device->GetCamera();
+
+ const auto window_width = static_cast<std::size_t>(current_config.window_of_interest.width);
+ const auto window_height = static_cast<std::size_t>(current_config.window_of_interest.height);
+ const auto window_start_x = static_cast<std::size_t>(current_config.window_of_interest.x);
+ const auto window_start_y = static_cast<std::size_t>(current_config.window_of_interest.y);
+
+ const std::size_t block_width = window_width / Columns;
+ const std::size_t block_height = window_height / Rows;
+
+ for (std::size_t row = 0; row < Rows; row++) {
+ for (std::size_t column = 0; column < Columns; column++) {
+ const size_t x_pos = (column * block_width) + window_start_x;
+ const size_t y_pos = (row * block_height) + window_start_y;
+ auto& statistic = next_state.statistic[column + (row * Columns)];
+ statistic = GetStatistic(camera_data.data, x_pos, y_pos, block_width, block_height);
+ }
+ }
+
+ next_state.sampling_number = camera_data.sample;
+ next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count();
+ next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
+ shared_memory->moment_lifo.WriteNextEntry(next_state);
+
+ if (!IsProcessorActive()) {
+ StartProcessor();
+ }
+}
+
+u8 MomentProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const {
+ if ((y * ImageWidth) + x >= data.size()) {
+ return 0;
+ }
+ return data[(y * ImageWidth) + x];
+}
+
+MomentProcessor::MomentStatistic MomentProcessor::GetStatistic(const std::vector<u8>& data,
+ std::size_t start_x,
+ std::size_t start_y,
+ std::size_t width,
+ std::size_t height) const {
+ // The actual implementation is always 320x240
+ static constexpr std::size_t RealWidth = 320;
+ static constexpr std::size_t RealHeight = 240;
+ static constexpr std::size_t Threshold = 30;
+ MomentStatistic statistic{};
+ std::size_t active_points{};
+
+ // Sum all data points on the block that meet with the threshold
+ for (std::size_t y = 0; y < width; y++) {
+ for (std::size_t x = 0; x < height; x++) {
+ const size_t x_pos = x + start_x;
+ const size_t y_pos = y + start_y;
+ const auto pixel =
+ GetPixel(data, x_pos * ImageWidth / RealWidth, y_pos * ImageHeight / RealHeight);
+
+ if (pixel < Threshold) {
+ continue;
+ }
+
+ statistic.average_intensity += pixel;
+
+ statistic.centroid.x += static_cast<float>(x_pos);
+ statistic.centroid.y += static_cast<float>(y_pos);
+
+ active_points++;
+ }
+ }
+
+ // Return an empty field if no points were available
+ if (active_points == 0) {
+ return {};
+ }
+
+ // Finally calculate the actual centroid and average intensity
+ statistic.centroid.x /= static_cast<float>(active_points);
+ statistic.centroid.y /= static_cast<float>(active_points);
+ statistic.average_intensity /= static_cast<f32>(width * height);
+
+ return statistic;
+}
+
void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig config) {
current_config.camera_config.exposure_time = config.camera_config.exposure_time;
current_config.camera_config.gain = config.camera_config.gain;
@@ -29,6 +142,8 @@ void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig conf
current_config.preprocess =
static_cast<Core::IrSensor::MomentProcessorPreprocess>(config.preprocess);
current_config.preprocess_intensity_threshold = config.preprocess_intensity_threshold;
+
+ npad_device->SetCameraFormat(format);
}
} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.h b/src/core/hle/service/hid/irsensor/moment_processor.h
index d4bd22e0f..398cfbdc1 100644
--- a/src/core/hle/service/hid/irsensor/moment_processor.h
+++ b/src/core/hle/service/hid/irsensor/moment_processor.h
@@ -6,12 +6,22 @@
#include "common/bit_field.h"
#include "common/common_types.h"
#include "core/hid/irs_types.h"
+#include "core/hle/service/hid/irs_ring_lifo.h"
#include "core/hle/service/hid/irsensor/processor_base.h"
+namespace Core {
+class System;
+}
+
+namespace Core::HID {
+class EmulatedController;
+} // namespace Core::HID
+
namespace Service::IRS {
class MomentProcessor final : public ProcessorBase {
public:
- explicit MomentProcessor(Core::IrSensor::DeviceFormat& device_format);
+ explicit MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
+ std::size_t npad_index);
~MomentProcessor() override;
// Called when the processor is initialized
@@ -27,6 +37,9 @@ public:
void SetConfig(Core::IrSensor::PackedMomentProcessorConfig config);
private:
+ static constexpr std::size_t Columns = 8;
+ static constexpr std::size_t Rows = 6;
+
// This is nn::irsensor::MomentProcessorConfig
struct MomentProcessorConfig {
Core::IrSensor::CameraConfig camera_config;
@@ -50,12 +63,29 @@ private:
u64 timestamp;
Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
INSERT_PADDING_BYTES(4);
- std::array<MomentStatistic, 0x30> stadistic;
+ std::array<MomentStatistic, Columns * Rows> statistic;
};
static_assert(sizeof(MomentProcessorState) == 0x258, "MomentProcessorState is an invalid size");
+ struct MomentSharedMemory {
+ Service::IRS::Lifo<MomentProcessorState, 6> moment_lifo;
+ };
+ static_assert(sizeof(MomentSharedMemory) == 0xE20, "MomentSharedMemory is an invalid size");
+
+ void OnControllerUpdate(Core::HID::ControllerTriggerType type);
+ u8 GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const;
+ MomentStatistic GetStatistic(const std::vector<u8>& data, std::size_t start_x,
+ std::size_t start_y, std::size_t width, std::size_t height) const;
+
+ MomentSharedMemory* shared_memory = nullptr;
+ MomentProcessorState next_state{};
+
MomentProcessorConfig current_config{};
Core::IrSensor::DeviceFormat& device;
+ Core::HID::EmulatedController* npad_device;
+ int callback_key{};
+
+ Core::System& system;
};
} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp
new file mode 100644
index 000000000..e76d4eea9
--- /dev/null
+++ b/src/core/hle/service/hid/resource_manager.cpp
@@ -0,0 +1,241 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/core_timing.h"
+#include "core/hid/hid_core.h"
+#include "core/hle/kernel/k_shared_memory.h"
+#include "core/hle/service/hid/resource_manager.h"
+#include "core/hle/service/ipc_helpers.h"
+
+#include "core/hle/service/hid/controllers/console_six_axis.h"
+#include "core/hle/service/hid/controllers/debug_pad.h"
+#include "core/hle/service/hid/controllers/gesture.h"
+#include "core/hle/service/hid/controllers/keyboard.h"
+#include "core/hle/service/hid/controllers/mouse.h"
+#include "core/hle/service/hid/controllers/npad.h"
+#include "core/hle/service/hid/controllers/palma.h"
+#include "core/hle/service/hid/controllers/seven_six_axis.h"
+#include "core/hle/service/hid/controllers/six_axis.h"
+#include "core/hle/service/hid/controllers/stubbed.h"
+#include "core/hle/service/hid/controllers/touchscreen.h"
+#include "core/hle/service/hid/controllers/xpad.h"
+
+namespace Service::HID {
+
+// Updating period for each HID device.
+// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
+// Correct npad_update_ns is 4ms this is overclocked to lower input lag
+constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
+constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
+constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
+constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
+
+ResourceManager::ResourceManager(Core::System& system_)
+ : system{system_}, service_context{system_, "hid"} {}
+
+ResourceManager::~ResourceManager() = default;
+
+void ResourceManager::Initialize() {
+ if (is_initialized) {
+ return;
+ }
+
+ u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
+ debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory);
+ mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory);
+ debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory);
+ keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory);
+ unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory);
+ npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context);
+ gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory);
+ touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory);
+ xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory);
+
+ palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context);
+
+ home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory);
+ sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory);
+ capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory);
+
+ six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
+ console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory);
+ seven_six_axis = std::make_shared<SevenSixAxis>(system);
+
+ home_button->SetCommonHeaderOffset(0x4C00);
+ sleep_button->SetCommonHeaderOffset(0x4E00);
+ capture_button->SetCommonHeaderOffset(0x5000);
+ unique_pad->SetCommonHeaderOffset(0x5A00);
+ debug_mouse->SetCommonHeaderOffset(0x3DC00);
+
+ // Homebrew doesn't try to activate some controllers, so we activate them by default
+ npad->Activate();
+ six_axis->Activate();
+ touch_screen->Activate();
+
+ system.HIDCore().ReloadInputDevices();
+ is_initialized = true;
+}
+std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const {
+ return capture_button;
+}
+
+std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const {
+ return console_six_axis;
+}
+
+std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const {
+ return debug_mouse;
+}
+
+std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const {
+ return debug_pad;
+}
+
+std::shared_ptr<Gesture> ResourceManager::GetGesture() const {
+ return gesture;
+}
+
+std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const {
+ return home_button;
+}
+
+std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const {
+ return keyboard;
+}
+
+std::shared_ptr<Mouse> ResourceManager::GetMouse() const {
+ return mouse;
+}
+
+std::shared_ptr<NPad> ResourceManager::GetNpad() const {
+ return npad;
+}
+
+std::shared_ptr<Palma> ResourceManager::GetPalma() const {
+ return palma;
+}
+
+std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const {
+ return seven_six_axis;
+}
+
+std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const {
+ return six_axis;
+}
+
+std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const {
+ return sleep_button;
+}
+
+std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const {
+ return touch_screen;
+}
+
+std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
+ return unique_pad;
+}
+
+void ResourceManager::UpdateControllers(std::uintptr_t user_data,
+ std::chrono::nanoseconds ns_late) {
+ auto& core_timing = system.CoreTiming();
+ debug_pad->OnUpdate(core_timing);
+ unique_pad->OnUpdate(core_timing);
+ gesture->OnUpdate(core_timing);
+ touch_screen->OnUpdate(core_timing);
+ palma->OnUpdate(core_timing);
+ home_button->OnUpdate(core_timing);
+ sleep_button->OnUpdate(core_timing);
+ capture_button->OnUpdate(core_timing);
+ xpad->OnUpdate(core_timing);
+}
+
+void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+ auto& core_timing = system.CoreTiming();
+ npad->OnUpdate(core_timing);
+}
+
+void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data,
+ std::chrono::nanoseconds ns_late) {
+ auto& core_timing = system.CoreTiming();
+ mouse->OnUpdate(core_timing);
+ debug_mouse->OnUpdate(core_timing);
+ keyboard->OnUpdate(core_timing);
+}
+
+void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+ auto& core_timing = system.CoreTiming();
+ six_axis->OnUpdate(core_timing);
+ seven_six_axis->OnUpdate(core_timing);
+ console_six_axis->OnUpdate(core_timing);
+}
+
+IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource)
+ : ServiceFramework{system_, "IAppletResource"} {
+ static const FunctionInfo functions[] = {
+ {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
+ };
+ RegisterHandlers(functions);
+
+ resource->Initialize();
+
+ // Register update callbacks
+ npad_update_event = Core::Timing::CreateEvent(
+ "HID::UpdatePadCallback",
+ [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
+ -> std::optional<std::chrono::nanoseconds> {
+ const auto guard = LockService();
+ resource->UpdateNpad(user_data, ns_late);
+ return std::nullopt;
+ });
+ default_update_event = Core::Timing::CreateEvent(
+ "HID::UpdateDefaultCallback",
+ [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
+ -> std::optional<std::chrono::nanoseconds> {
+ const auto guard = LockService();
+ resource->UpdateControllers(user_data, ns_late);
+ return std::nullopt;
+ });
+ mouse_keyboard_update_event = Core::Timing::CreateEvent(
+ "HID::UpdateMouseKeyboardCallback",
+ [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
+ -> std::optional<std::chrono::nanoseconds> {
+ const auto guard = LockService();
+ resource->UpdateMouseKeyboard(user_data, ns_late);
+ return std::nullopt;
+ });
+ motion_update_event = Core::Timing::CreateEvent(
+ "HID::UpdateMotionCallback",
+ [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
+ -> std::optional<std::chrono::nanoseconds> {
+ const auto guard = LockService();
+ resource->UpdateMotion(user_data, ns_late);
+ return std::nullopt;
+ });
+
+ system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
+ system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
+ default_update_event);
+ system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
+ mouse_keyboard_update_event);
+ system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
+ motion_update_event);
+}
+
+IAppletResource::~IAppletResource() {
+ system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(default_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
+}
+
+void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_HID, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(&system.Kernel().GetHidSharedMem());
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h
new file mode 100644
index 000000000..2b6a9b5e6
--- /dev/null
+++ b/src/core/hle/service/hid/resource_manager.h
@@ -0,0 +1,111 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/service.h"
+
+namespace Core::Timing {
+struct EventType;
+}
+
+namespace Service::HID {
+class Controller_Stubbed;
+class ConsoleSixAxis;
+class DebugPad;
+class Gesture;
+class Keyboard;
+class Mouse;
+class NPad;
+class Palma;
+class SevenSixAxis;
+class SixAxis;
+class TouchScreen;
+class XPad;
+
+using CaptureButton = Controller_Stubbed;
+using DebugMouse = Controller_Stubbed;
+using HomeButton = Controller_Stubbed;
+using SleepButton = Controller_Stubbed;
+using UniquePad = Controller_Stubbed;
+
+class ResourceManager {
+
+public:
+ explicit ResourceManager(Core::System& system_);
+ ~ResourceManager();
+
+ void Initialize();
+
+ std::shared_ptr<CaptureButton> GetCaptureButton() const;
+ std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const;
+ std::shared_ptr<DebugMouse> GetDebugMouse() const;
+ std::shared_ptr<DebugPad> GetDebugPad() const;
+ std::shared_ptr<Gesture> GetGesture() const;
+ std::shared_ptr<HomeButton> GetHomeButton() const;
+ std::shared_ptr<Keyboard> GetKeyboard() const;
+ std::shared_ptr<Mouse> GetMouse() const;
+ std::shared_ptr<NPad> GetNpad() const;
+ std::shared_ptr<Palma> GetPalma() const;
+ std::shared_ptr<SevenSixAxis> GetSevenSixAxis() const;
+ std::shared_ptr<SixAxis> GetSixAxis() const;
+ std::shared_ptr<SleepButton> GetSleepButton() const;
+ std::shared_ptr<TouchScreen> GetTouchScreen() const;
+ std::shared_ptr<UniquePad> GetUniquePad() const;
+
+ void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+
+private:
+ bool is_initialized{false};
+
+ std::shared_ptr<CaptureButton> capture_button = nullptr;
+ std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr;
+ std::shared_ptr<DebugMouse> debug_mouse = nullptr;
+ std::shared_ptr<DebugPad> debug_pad = nullptr;
+ std::shared_ptr<Gesture> gesture = nullptr;
+ std::shared_ptr<HomeButton> home_button = nullptr;
+ std::shared_ptr<Keyboard> keyboard = nullptr;
+ std::shared_ptr<Mouse> mouse = nullptr;
+ std::shared_ptr<NPad> npad = nullptr;
+ std::shared_ptr<Palma> palma = nullptr;
+ std::shared_ptr<SevenSixAxis> seven_six_axis = nullptr;
+ std::shared_ptr<SixAxis> six_axis = nullptr;
+ std::shared_ptr<SleepButton> sleep_button = nullptr;
+ std::shared_ptr<TouchScreen> touch_screen = nullptr;
+ std::shared_ptr<UniquePad> unique_pad = nullptr;
+ std::shared_ptr<XPad> xpad = nullptr;
+
+ // TODO: Create these resources
+ // std::shared_ptr<AudioControl> audio_control = nullptr;
+ // std::shared_ptr<ButtonConfig> button_config = nullptr;
+ // std::shared_ptr<Config> config = nullptr;
+ // std::shared_ptr<Connection> connection = nullptr;
+ // std::shared_ptr<CustomConfig> custom_config = nullptr;
+ // std::shared_ptr<Digitizer> digitizer = nullptr;
+ // std::shared_ptr<Hdls> hdls = nullptr;
+ // std::shared_ptr<PlayReport> play_report = nullptr;
+ // std::shared_ptr<Rail> rail = nullptr;
+
+ Core::System& system;
+ KernelHelpers::ServiceContext service_context;
+};
+
+class IAppletResource final : public ServiceFramework<IAppletResource> {
+public:
+ explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource);
+ ~IAppletResource() override;
+
+private:
+ void GetSharedMemoryHandle(HLERequestContext& ctx);
+
+ std::shared_ptr<Core::Timing::EventType> npad_update_event;
+ std::shared_ptr<Core::Timing::EventType> default_update_event;
+ std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
+ std::shared_ptr<Core::Timing::EventType> motion_update_event;
+};
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/ring_lifo.h b/src/core/hle/service/hid/ring_lifo.h
index 65eb7ea02..0816784e0 100644
--- a/src/core/hle/service/hid/ring_lifo.h
+++ b/src/core/hle/service/hid/ring_lifo.h
@@ -32,15 +32,15 @@ struct Lifo {
}
std::size_t GetPreviousEntryIndex() const {
- return static_cast<size_t>((buffer_tail + total_buffer_count - 1) % total_buffer_count);
+ return static_cast<size_t>((buffer_tail + max_buffer_size - 1) % max_buffer_size);
}
std::size_t GetNextEntryIndex() const {
- return static_cast<size_t>((buffer_tail + 1) % total_buffer_count);
+ return static_cast<size_t>((buffer_tail + 1) % max_buffer_size);
}
void WriteNextEntry(const State& new_state) {
- if (buffer_count < total_buffer_count - 1) {
+ if (buffer_count < static_cast<s64>(max_buffer_size) - 1) {
buffer_count++;
}
buffer_tail = GetNextEntryIndex();
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index 7927f8264..961f89a14 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -115,12 +115,20 @@ public:
{400, nullptr, "InitializeSystem"},
{401, nullptr, "FinalizeSystem"},
{402, nullptr, "SetOperationMode"},
- {403, nullptr, "InitializeSystem2"},
+ {403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"},
};
// clang-format on
RegisterHandlers(functions);
}
+
+private:
+ void InitializeSystem2(HLERequestContext& ctx) {
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
};
class IUserLocalCommunicationService final
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index c73035c77..97b6a9385 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -286,9 +286,14 @@ public:
rb.Push(ResultSuccess);
}
- bool ValidateRegionForMap(Kernel::KPageTable& page_table, VAddr start, std::size_t size) const {
+ bool ValidateRegionForMap(Kernel::KProcessPageTable& page_table, VAddr start,
+ std::size_t size) const {
const std::size_t padding_size{page_table.GetNumGuardPages() * Kernel::PageSize};
- const auto start_info{page_table.QueryInfo(start - 1)};
+
+ Kernel::KMemoryInfo start_info;
+ Kernel::Svc::PageInfo page_info;
+ R_ASSERT(
+ page_table.QueryInfo(std::addressof(start_info), std::addressof(page_info), start - 1));
if (start_info.GetState() != Kernel::KMemoryState::Free) {
return {};
@@ -298,7 +303,9 @@ public:
return {};
}
- const auto end_info{page_table.QueryInfo(start + size)};
+ Kernel::KMemoryInfo end_info;
+ R_ASSERT(page_table.QueryInfo(std::addressof(end_info), std::addressof(page_info),
+ start + size));
if (end_info.GetState() != Kernel::KMemoryState::Free) {
return {};
@@ -307,7 +314,7 @@ public:
return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize());
}
- Result GetAvailableMapRegion(Kernel::KPageTable& page_table, u64 size, VAddr& out_addr) {
+ Result GetAvailableMapRegion(Kernel::KProcessPageTable& page_table, u64 size, VAddr& out_addr) {
size = Common::AlignUp(size, Kernel::PageSize);
size += page_table.GetNumGuardPages() * Kernel::PageSize * 4;
@@ -391,12 +398,8 @@ public:
if (bss_size) {
auto block_guard = detail::ScopeExit([&] {
- page_table.UnmapCodeMemory(
- addr + nro_size, bss_addr, bss_size,
- Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange);
- page_table.UnmapCodeMemory(
- addr, nro_addr, nro_size,
- Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange);
+ page_table.UnmapCodeMemory(addr + nro_size, bss_addr, bss_size);
+ page_table.UnmapCodeMemory(addr, nro_addr, nro_size);
});
const Result result{page_table.MapCodeMemory(addr + nro_size, bss_addr, bss_size)};
@@ -578,21 +581,17 @@ public:
auto& page_table{system.ApplicationProcess()->GetPageTable()};
if (info.bss_size != 0) {
- R_TRY(page_table.UnmapCodeMemory(
- info.nro_address + info.text_size + info.ro_size + info.data_size, info.bss_address,
- info.bss_size, Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
+ R_TRY(page_table.UnmapCodeMemory(info.nro_address + info.text_size + info.ro_size +
+ info.data_size,
+ info.bss_address, info.bss_size));
}
- R_TRY(page_table.UnmapCodeMemory(
- info.nro_address + info.text_size + info.ro_size,
- info.src_addr + info.text_size + info.ro_size, info.data_size,
- Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
- R_TRY(page_table.UnmapCodeMemory(
- info.nro_address + info.text_size, info.src_addr + info.text_size, info.ro_size,
- Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
- R_TRY(page_table.UnmapCodeMemory(
- info.nro_address, info.src_addr, info.text_size,
- Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
+ R_TRY(page_table.UnmapCodeMemory(info.nro_address + info.text_size + info.ro_size,
+ info.src_addr + info.text_size + info.ro_size,
+ info.data_size));
+ R_TRY(page_table.UnmapCodeMemory(info.nro_address + info.text_size,
+ info.src_addr + info.text_size, info.ro_size));
+ R_TRY(page_table.UnmapCodeMemory(info.nro_address, info.src_addr, info.text_size));
return ResultSuccess;
}
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index a71d26157..ad534177d 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -7,6 +7,7 @@
#include "core/core.h"
#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
+#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/nfc/common/device.h"
#include "core/hle/service/nfc/common/device_manager.h"
@@ -24,7 +25,7 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex
for (u32 device_index = 0; device_index < devices.size(); device_index++) {
devices[device_index] =
- std::make_shared<NfcDevice>(Core::HID::IndexToNpadIdType(device_index), system,
+ std::make_shared<NfcDevice>(HID::IndexToNpadIdType(device_index), system,
service_context, availability_change_event);
}
diff --git a/src/core/hle/service/nvdrv/devices/ioctl_serialization.h b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h
new file mode 100644
index 000000000..b12bcd138
--- /dev/null
+++ b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h
@@ -0,0 +1,159 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <span>
+#include <vector>
+
+#include "common/concepts.h"
+#include "core/hle/service/nvdrv/devices/nvdevice.h"
+
+namespace Service::Nvidia::Devices {
+
+struct IoctlOneArgTraits {
+ template <typename T, typename R, typename A, typename... B>
+ static A GetFirstArgImpl(R (T::*)(A, B...));
+};
+
+struct IoctlTwoArgTraits {
+ template <typename T, typename R, typename A, typename B, typename... C>
+ static A GetFirstArgImpl(R (T::*)(A, B, C...));
+
+ template <typename T, typename R, typename A, typename B, typename... C>
+ static B GetSecondArgImpl(R (T::*)(A, B, C...));
+};
+
+struct Null {};
+
+// clang-format off
+
+template <typename FixedArg, typename VarArg, typename InlInVarArg, typename InlOutVarArg, typename F>
+NvResult WrapGeneric(F&& callable, std::span<const u8> input, std::span<const u8> inline_input, std::span<u8> output, std::span<u8> inline_output) {
+ constexpr bool HasFixedArg = !std::is_same_v<FixedArg, Null>;
+ constexpr bool HasVarArg = !std::is_same_v<VarArg, Null>;
+ constexpr bool HasInlInVarArg = !std::is_same_v<InlInVarArg, Null>;
+ constexpr bool HasInlOutVarArg = !std::is_same_v<InlOutVarArg, Null>;
+
+ // Declare the fixed-size input value.
+ FixedArg fixed{};
+ size_t var_offset = 0;
+
+ if constexpr (HasFixedArg) {
+ // Read the fixed-size input value.
+ var_offset = std::min(sizeof(FixedArg), input.size());
+ if (var_offset > 0) {
+ std::memcpy(&fixed, input.data(), var_offset);
+ }
+ }
+
+ // Read the variable-sized inputs.
+ const size_t num_var_args = HasVarArg ? ((input.size() - var_offset) / sizeof(VarArg)) : 0;
+ std::vector<VarArg> var_args(num_var_args);
+ if constexpr (HasVarArg) {
+ if (num_var_args > 0) {
+ std::memcpy(var_args.data(), input.data() + var_offset, num_var_args * sizeof(VarArg));
+ }
+ }
+
+ const size_t num_inl_in_var_args = HasInlInVarArg ? (inline_input.size() / sizeof(InlInVarArg)) : 0;
+ std::vector<InlInVarArg> inl_in_var_args(num_inl_in_var_args);
+ if constexpr (HasInlInVarArg) {
+ if (num_inl_in_var_args > 0) {
+ std::memcpy(inl_in_var_args.data(), inline_input.data(), num_inl_in_var_args * sizeof(InlInVarArg));
+ }
+ }
+
+ // Construct inline output data.
+ const size_t num_inl_out_var_args = HasInlOutVarArg ? (inline_output.size() / sizeof(InlOutVarArg)) : 0;
+ std::vector<InlOutVarArg> inl_out_var_args(num_inl_out_var_args);
+
+ // Perform the call.
+ NvResult result = callable(fixed, var_args, inl_in_var_args, inl_out_var_args);
+
+ // Copy outputs.
+ if constexpr (HasFixedArg) {
+ if (output.size() > 0) {
+ std::memcpy(output.data(), &fixed, std::min(output.size(), sizeof(FixedArg)));
+ }
+ }
+
+ if constexpr (HasVarArg) {
+ if (num_var_args > 0 && output.size() > var_offset) {
+ const size_t max_var_size = output.size() - var_offset;
+ std::memcpy(output.data() + var_offset, var_args.data(), std::min(max_var_size, num_var_args * sizeof(VarArg)));
+ }
+ }
+
+ // Copy inline outputs.
+ if constexpr (HasInlOutVarArg) {
+ if (num_inl_out_var_args > 0) {
+ std::memcpy(inline_output.data(), inl_out_var_args.data(), num_inl_out_var_args * sizeof(InlOutVarArg));
+ }
+ }
+
+ // We're done.
+ return result;
+}
+
+template <typename Self, typename F, typename... Rest>
+NvResult WrapFixed(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, Rest&&... rest) {
+ using FixedArg = typename std::remove_reference_t<decltype(IoctlOneArgTraits::GetFirstArgImpl(callable))>;
+
+ const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult {
+ return (self->*callable)(fixed, std::forward<Rest>(rest)...);
+ };
+
+ return WrapGeneric<FixedArg, Null, Null, Null>(std::move(Callable), input, {}, output, {});
+}
+
+template <typename Self, typename F, typename... Rest>
+NvResult WrapFixedInlOut(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, std::span<u8> inline_output, Rest&&... rest) {
+ using FixedArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetFirstArgImpl(callable))>;
+ using InlOutVarArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetSecondArgImpl(callable))>::value_type;
+
+ const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult {
+ return (self->*callable)(fixed, inl_out, std::forward<Rest>(rest)...);
+ };
+
+ return WrapGeneric<FixedArg, Null, Null, InlOutVarArg>(std::move(Callable), input, {}, output, inline_output);
+}
+
+template <typename Self, typename F, typename... Rest>
+NvResult WrapVariable(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, Rest&&... rest) {
+ using VarArg = typename std::remove_reference_t<decltype(IoctlOneArgTraits::GetFirstArgImpl(callable))>::value_type;
+
+ const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult {
+ return (self->*callable)(var, std::forward<Rest>(rest)...);
+ };
+
+ return WrapGeneric<Null, VarArg, Null, Null>(std::move(Callable), input, {}, output, {});
+}
+
+template <typename Self, typename F, typename... Rest>
+NvResult WrapFixedVariable(Self* self, F&& callable, std::span<const u8> input, std::span<u8> output, Rest&&... rest) {
+ using FixedArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetFirstArgImpl(callable))>;
+ using VarArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetSecondArgImpl(callable))>::value_type;
+
+ const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult {
+ return (self->*callable)(fixed, var, std::forward<Rest>(rest)...);
+ };
+
+ return WrapGeneric<FixedArg, VarArg, Null, Null>(std::move(Callable), input, {}, output, {});
+}
+
+template <typename Self, typename F, typename... Rest>
+NvResult WrapFixedInlIn(Self* self, F&& callable, std::span<const u8> input, std::span<const u8> inline_input, std::span<u8> output, Rest&&... rest) {
+ using FixedArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetFirstArgImpl(callable))>;
+ using InlInVarArg = typename std::remove_reference_t<decltype(IoctlTwoArgTraits::GetSecondArgImpl(callable))>::value_type;
+
+ const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult {
+ return (self->*callable)(fixed, inl_in, std::forward<Rest>(rest)...);
+ };
+
+ return WrapGeneric<FixedArg, Null, InlInVarArg, Null>(std::move(Callable), input, inline_input, output, {});
+}
+
+// clang-format on
+
+} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 7d7bb8687..6b3639008 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -11,6 +11,7 @@
#include "core/core.h"
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/core/nvmap.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
#include "core/hle/service/nvdrv/nvdrv.h"
@@ -33,21 +34,21 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> i
case 'A':
switch (command.cmd) {
case 0x1:
- return BindChannel(input, output);
+ return WrapFixed(this, &nvhost_as_gpu::BindChannel, input, output);
case 0x2:
- return AllocateSpace(input, output);
+ return WrapFixed(this, &nvhost_as_gpu::AllocateSpace, input, output);
case 0x3:
- return FreeSpace(input, output);
+ return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output);
case 0x5:
- return UnmapBuffer(input, output);
+ return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output);
case 0x6:
- return MapBufferEx(input, output);
+ return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output);
case 0x8:
- return GetVARegions(input, output);
+ return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output);
case 0x9:
- return AllocAsEx(input, output);
+ return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output);
case 0x14:
- return Remap(input, output);
+ return WrapVariable(this, &nvhost_as_gpu::Remap, input, output);
default:
break;
}
@@ -72,7 +73,8 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i
case 'A':
switch (command.cmd) {
case 0x8:
- return GetVARegions(input, output, inline_output);
+ return WrapFixedInlOut(this, &nvhost_as_gpu::GetVARegions3, input, output,
+ inline_output);
default:
break;
}
@@ -87,10 +89,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i
void nvhost_as_gpu::OnOpen(DeviceFD fd) {}
void nvhost_as_gpu::OnClose(DeviceFD fd) {}
-NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> output) {
- IoctlAllocAsEx params{};
- std::memcpy(&params, input.data(), input.size());
-
+NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) {
LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size);
std::scoped_lock lock(mutex);
@@ -141,10 +140,7 @@ NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> outpu
return NvResult::Success;
}
-NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> output) {
- IoctlAllocSpace params{};
- std::memcpy(&params, input.data(), input.size());
-
+NvResult nvhost_as_gpu::AllocateSpace(IoctlAllocSpace& params) {
LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages,
params.page_size, params.flags);
@@ -194,7 +190,6 @@ NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> o
.big_pages = params.page_size != VM::YUZU_PAGESIZE,
};
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
@@ -222,10 +217,7 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
mapping_map.erase(offset);
}
-NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> output) {
- IoctlFreeSpace params{};
- std::memcpy(&params, input.data(), input.size());
-
+NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) {
LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset,
params.pages, params.page_size);
@@ -264,18 +256,11 @@ NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> outpu
return NvResult::BadValue;
}
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) {
- const auto num_entries = input.size() / sizeof(IoctlRemapEntry);
-
- LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries);
-
- std::scoped_lock lock(mutex);
- entries.resize_destructive(num_entries);
- std::memcpy(entries.data(), input.data(), input.size());
+NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) {
+ LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size());
if (!vm.initialised) {
return NvResult::BadValue;
@@ -317,14 +302,10 @@ NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) {
}
}
- std::memcpy(output.data(), entries.data(), output.size());
return NvResult::Success;
}
-NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> output) {
- IoctlMapBufferEx params{};
- std::memcpy(&params, input.data(), input.size());
-
+NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) {
LOG_DEBUG(Service_NVDRV,
"called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}"
", offset={}",
@@ -421,14 +402,10 @@ NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> out
mapping_map[params.offset] = mapping;
}
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> output) {
- IoctlUnmapBuffer params{};
- std::memcpy(&params, input.data(), input.size());
-
+NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) {
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
std::scoped_lock lock(mutex);
@@ -464,9 +441,7 @@ NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> out
return NvResult::Success;
}
-NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::span<u8> output) {
- IoctlBindChannel params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_as_gpu::BindChannel(IoctlBindChannel& params) {
LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd);
auto gpu_channel_device = module.GetDevice<nvhost_gpu>(params.fd);
@@ -493,10 +468,7 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) {
};
}
-NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output) {
- IoctlGetVaRegions params{};
- std::memcpy(&params, input.data(), input.size());
-
+NvResult nvhost_as_gpu::GetVARegions1(IoctlGetVaRegions& params) {
LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
params.buf_size);
@@ -508,15 +480,10 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> ou
GetVARegionsImpl(params);
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output,
- std::span<u8> inline_output) {
- IoctlGetVaRegions params{};
- std::memcpy(&params, input.data(), input.size());
-
+NvResult nvhost_as_gpu::GetVARegions3(IoctlGetVaRegions& params, std::span<VaRegion> regions) {
LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
params.buf_size);
@@ -528,9 +495,10 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> ou
GetVARegionsImpl(params);
- std::memcpy(output.data(), &params, output.size());
- std::memcpy(inline_output.data(), &params.regions[0], sizeof(VaRegion));
- std::memcpy(inline_output.data() + sizeof(VaRegion), &params.regions[1], sizeof(VaRegion));
+ const size_t num_regions = std::min(params.regions.size(), regions.size());
+ for (size_t i = 0; i < num_regions; i++) {
+ regions[i] = params.regions[i];
+ }
return NvResult::Success;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
index 2af3e1260..932997e75 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -139,18 +139,17 @@ private:
static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2,
"IoctlGetVaRegions is incorrect size");
- NvResult AllocAsEx(std::span<const u8> input, std::span<u8> output);
- NvResult AllocateSpace(std::span<const u8> input, std::span<u8> output);
- NvResult Remap(std::span<const u8> input, std::span<u8> output);
- NvResult MapBufferEx(std::span<const u8> input, std::span<u8> output);
- NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output);
- NvResult FreeSpace(std::span<const u8> input, std::span<u8> output);
- NvResult BindChannel(std::span<const u8> input, std::span<u8> output);
+ NvResult AllocAsEx(IoctlAllocAsEx& params);
+ NvResult AllocateSpace(IoctlAllocSpace& params);
+ NvResult Remap(std::span<IoctlRemapEntry> params);
+ NvResult MapBufferEx(IoctlMapBufferEx& params);
+ NvResult UnmapBuffer(IoctlUnmapBuffer& params);
+ NvResult FreeSpace(IoctlFreeSpace& params);
+ NvResult BindChannel(IoctlBindChannel& params);
void GetVARegionsImpl(IoctlGetVaRegions& params);
- NvResult GetVARegions(std::span<const u8> input, std::span<u8> output);
- NvResult GetVARegions(std::span<const u8> input, std::span<u8> output,
- std::span<u8> inline_output);
+ NvResult GetVARegions1(IoctlGetVaRegions& params);
+ NvResult GetVARegions3(IoctlGetVaRegions& params, std::span<VaRegion> regions);
void FreeMappingLocked(u64 offset);
@@ -213,7 +212,6 @@ private:
bool initialised{};
} vm;
std::shared_ptr<Tegra::MemoryManager> gmmu;
- Common::ScratchBuffer<IoctlRemapEntry> entries;
// s32 channel{};
// u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE};
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 4d55554b4..b8dd34e24 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -14,6 +14,7 @@
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
#include "video_core/gpu.h"
#include "video_core/host1x/host1x.h"
@@ -40,19 +41,19 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inp
case 0x0:
switch (command.cmd) {
case 0x1b:
- return NvOsGetConfigU32(input, output);
+ return WrapFixed(this, &nvhost_ctrl::NvOsGetConfigU32, input, output);
case 0x1c:
- return IocCtrlClearEventWait(input, output);
+ return WrapFixed(this, &nvhost_ctrl::IocCtrlClearEventWait, input, output);
case 0x1d:
- return IocCtrlEventWait(input, output, true);
+ return WrapFixed(this, &nvhost_ctrl::IocCtrlEventWait, input, output, true);
case 0x1e:
- return IocCtrlEventWait(input, output, false);
+ return WrapFixed(this, &nvhost_ctrl::IocCtrlEventWait, input, output, false);
case 0x1f:
- return IocCtrlEventRegister(input, output);
+ return WrapFixed(this, &nvhost_ctrl::IocCtrlEventRegister, input, output);
case 0x20:
- return IocCtrlEventUnregister(input, output);
+ return WrapFixed(this, &nvhost_ctrl::IocCtrlEventUnregister, input, output);
case 0x21:
- return IocCtrlEventUnregisterBatch(input, output);
+ return WrapFixed(this, &nvhost_ctrl::IocCtrlEventUnregisterBatch, input, output);
}
break;
default:
@@ -79,25 +80,19 @@ void nvhost_ctrl::OnOpen(DeviceFD fd) {}
void nvhost_ctrl::OnClose(DeviceFD fd) {}
-NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output) {
- IocGetConfigParams params{};
- std::memcpy(&params, input.data(), sizeof(params));
+NvResult nvhost_ctrl::NvOsGetConfigU32(IocGetConfigParams& params) {
LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(),
params.param_str.data());
return NvResult::ConfigVarNotFound; // Returns error on production mode
}
-NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::span<u8> output,
- bool is_allocation) {
- IocCtrlEventWaitParams params{};
- std::memcpy(&params, input.data(), sizeof(params));
+NvResult nvhost_ctrl::IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_allocation) {
LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_allocation={}",
params.fence.id, params.fence.value, params.timeout, is_allocation);
bool must_unmark_fail = !is_allocation;
const u32 event_id = params.value.raw;
SCOPE_EXIT({
- std::memcpy(output.data(), &params, sizeof(params));
if (must_unmark_fail) {
events[event_id].fails = 0;
}
@@ -231,9 +226,7 @@ NvResult nvhost_ctrl::FreeEvent(u32 slot) {
return NvResult::Success;
}
-NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output) {
- IocCtrlEventRegisterParams params{};
- std::memcpy(&params, input.data(), sizeof(params));
+NvResult nvhost_ctrl::IocCtrlEventRegister(IocCtrlEventRegisterParams& params) {
const u32 event_id = params.user_event_id;
LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id);
if (event_id >= MaxNvEvents) {
@@ -252,9 +245,7 @@ NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::span<
return NvResult::Success;
}
-NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output) {
- IocCtrlEventUnregisterParams params{};
- std::memcpy(&params, input.data(), sizeof(params));
+NvResult nvhost_ctrl::IocCtrlEventUnregister(IocCtrlEventUnregisterParams& params) {
const u32 event_id = params.user_event_id & 0x00FF;
LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id);
@@ -262,9 +253,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::spa
return FreeEvent(event_id);
}
-NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output) {
- IocCtrlEventUnregisterBatchParams params{};
- std::memcpy(&params, input.data(), sizeof(params));
+NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(IocCtrlEventUnregisterBatchParams& params) {
u64 event_mask = params.user_events;
LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask);
@@ -280,10 +269,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, std
return NvResult::Success;
}
-NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output) {
- IocCtrlEventClearParams params{};
- std::memcpy(&params, input.data(), sizeof(params));
-
+NvResult nvhost_ctrl::IocCtrlClearEventWait(IocCtrlEventClearParams& params) {
u32 event_id = params.event_id.slot;
LOG_DEBUG(Service_NVDRV, "called, event_id: {:X}", event_id);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index 2efed4862..992124b60 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -186,12 +186,12 @@ private:
static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8,
"IocCtrlEventKill is incorrect size");
- NvResult NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output);
- NvResult IocCtrlEventWait(std::span<const u8> input, std::span<u8> output, bool is_allocation);
- NvResult IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output);
- NvResult IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output);
- NvResult IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output);
- NvResult IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output);
+ NvResult NvOsGetConfigU32(IocGetConfigParams& params);
+ NvResult IocCtrlEventRegister(IocCtrlEventRegisterParams& params);
+ NvResult IocCtrlEventUnregister(IocCtrlEventUnregisterParams& params);
+ NvResult IocCtrlEventUnregisterBatch(IocCtrlEventUnregisterBatchParams& params);
+ NvResult IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_allocation);
+ NvResult IocCtrlClearEventWait(IocCtrlEventClearParams& params);
NvResult FreeEvent(u32 slot);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 6081d92e9..61a2df121 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -6,6 +6,7 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "core/core_timing.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h"
#include "core/hle/service/nvdrv/nvdrv.h"
@@ -27,23 +28,23 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8>
case 'G':
switch (command.cmd) {
case 0x1:
- return ZCullGetCtxSize(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::ZCullGetCtxSize, input, output);
case 0x2:
- return ZCullGetInfo(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::ZCullGetInfo, input, output);
case 0x3:
- return ZBCSetTable(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::ZBCSetTable, input, output);
case 0x4:
- return ZBCQueryTable(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::ZBCQueryTable, input, output);
case 0x5:
- return GetCharacteristics(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::GetCharacteristics1, input, output);
case 0x6:
- return GetTPCMasks(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::GetTPCMasks1, input, output);
case 0x7:
- return FlushL2(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::FlushL2, input, output);
case 0x14:
- return GetActiveSlotMask(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output);
case 0x1c:
- return GetGpuTime(input, output);
+ return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output);
default:
break;
}
@@ -65,9 +66,11 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8>
case 'G':
switch (command.cmd) {
case 0x5:
- return GetCharacteristics(input, output, inline_output);
+ return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetCharacteristics3, input, output,
+ inline_output);
case 0x6:
- return GetTPCMasks(input, output, inline_output);
+ return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetTPCMasks3, input, output,
+ inline_output);
default:
break;
}
@@ -82,10 +85,8 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8>
void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {}
void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {}
-NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) {
LOG_DEBUG(Service_NVDRV, "called");
- IoctlCharacteristics params{};
- std::memcpy(&params, input.data(), input.size());
params.gc.arch = 0x120;
params.gc.impl = 0xb;
params.gc.rev = 0xa1;
@@ -123,15 +124,13 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::spa
params.gc.gr_compbit_store_base_hw = 0x0;
params.gpu_characteristics_buf_size = 0xA0;
params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED)
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output,
- std::span<u8> inline_output) {
+NvResult nvhost_ctrl_gpu::GetCharacteristics3(
+ IoctlCharacteristics& params, std::span<IoctlGpuCharacteristics> gpu_characteristics) {
LOG_DEBUG(Service_NVDRV, "called");
- IoctlCharacteristics params{};
- std::memcpy(&params, input.data(), input.size());
+
params.gc.arch = 0x120;
params.gc.impl = 0xb;
params.gc.rev = 0xa1;
@@ -169,70 +168,47 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::spa
params.gc.gr_compbit_store_base_hw = 0x0;
params.gpu_characteristics_buf_size = 0xA0;
params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED)
-
- std::memcpy(output.data(), &params, output.size());
- std::memcpy(inline_output.data(), &params.gc, inline_output.size());
+ if (!gpu_characteristics.empty()) {
+ gpu_characteristics.front() = params.gc;
+ }
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output) {
- IoctlGpuGetTpcMasksArgs params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_ctrl_gpu::GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params) {
LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size);
if (params.mask_buffer_size != 0) {
params.tcp_mask = 3;
}
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output,
- std::span<u8> inline_output) {
- IoctlGpuGetTpcMasksArgs params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_ctrl_gpu::GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask) {
LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size);
if (params.mask_buffer_size != 0) {
params.tcp_mask = 3;
}
- std::memcpy(output.data(), &params, output.size());
- std::memcpy(inline_output.data(), &params.tcp_mask, inline_output.size());
+ if (!tpc_mask.empty()) {
+ tpc_mask.front() = params.tcp_mask;
+ }
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::GetActiveSlotMask(IoctlActiveSlotMask& params) {
LOG_DEBUG(Service_NVDRV, "called");
- IoctlActiveSlotMask params{};
- if (input.size() > 0) {
- std::memcpy(&params, input.data(), input.size());
- }
params.slot = 0x07;
params.mask = 0x01;
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(IoctlZcullGetCtxSize& params) {
LOG_DEBUG(Service_NVDRV, "called");
-
- IoctlZcullGetCtxSize params{};
- if (input.size() > 0) {
- std::memcpy(&params, input.data(), input.size());
- }
params.size = 0x1;
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) {
LOG_DEBUG(Service_NVDRV, "called");
-
- IoctlNvgpuGpuZcullGetInfoArgs params{};
-
- if (input.size() > 0) {
- std::memcpy(&params, input.data(), input.size());
- }
-
params.width_align_pixels = 0x20;
params.height_align_pixels = 0x20;
params.pixel_squares_by_aliquots = 0x400;
@@ -243,53 +219,28 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::span<u8>
params.subregion_width_align_pixels = 0x20;
params.subregion_height_align_pixels = 0x40;
params.subregion_count = 0x10;
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
-
- IoctlZbcSetTable params{};
- std::memcpy(&params, input.data(), input.size());
// TODO(ogniK): What does this even actually do?
-
- // Prevent null pointer being passed as arg 1
- if (output.empty()) {
- LOG_WARNING(Service_NVDRV, "Avoiding passing null pointer to memcpy");
- } else {
- std::memcpy(output.data(), &params, output.size());
- }
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
-
- IoctlZbcQueryTable params{};
- std::memcpy(&params, input.data(), input.size());
- // TODO : To implement properly
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::FlushL2(IoctlFlushL2& params) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
-
- IoctlFlushL2 params{};
- std::memcpy(&params, input.data(), input.size());
- // TODO : To implement properly
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_ctrl_gpu::GetGpuTime(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_ctrl_gpu::GetGpuTime(IoctlGetGpuTime& params) {
LOG_DEBUG(Service_NVDRV, "called");
-
- IoctlGetGpuTime params{};
- std::memcpy(&params, input.data(), input.size());
params.gpu_time = static_cast<u64_le>(system.CoreTiming().GetGlobalTimeNs().count());
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
index 97995551c..d170299bd 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -151,21 +151,20 @@ private:
};
static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size");
- NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output);
- NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output,
- std::span<u8> inline_output);
-
- NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output);
- NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output,
- std::span<u8> inline_output);
-
- NvResult GetActiveSlotMask(std::span<const u8> input, std::span<u8> output);
- NvResult ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output);
- NvResult ZCullGetInfo(std::span<const u8> input, std::span<u8> output);
- NvResult ZBCSetTable(std::span<const u8> input, std::span<u8> output);
- NvResult ZBCQueryTable(std::span<const u8> input, std::span<u8> output);
- NvResult FlushL2(std::span<const u8> input, std::span<u8> output);
- NvResult GetGpuTime(std::span<const u8> input, std::span<u8> output);
+ NvResult GetCharacteristics1(IoctlCharacteristics& params);
+ NvResult GetCharacteristics3(IoctlCharacteristics& params,
+ std::span<IoctlGpuCharacteristics> gpu_characteristics);
+
+ NvResult GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params);
+ NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask);
+
+ NvResult GetActiveSlotMask(IoctlActiveSlotMask& params);
+ NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params);
+ NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params);
+ NvResult ZBCSetTable(IoctlZbcSetTable& params);
+ NvResult ZBCQueryTable(IoctlZbcQueryTable& params);
+ NvResult FlushL2(IoctlFlushL2& params);
+ NvResult GetGpuTime(IoctlGetGpuTime& params);
EventInterface& events_interface;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 46a25fcab..b0395c2f0 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -8,6 +8,7 @@
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/memory.h"
@@ -52,7 +53,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
case 0x0:
switch (command.cmd) {
case 0x3:
- return GetWaitbase(input, output);
+ return WrapFixed(this, &nvhost_gpu::GetWaitbase, input, output);
default:
break;
}
@@ -60,25 +61,25 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
case 'H':
switch (command.cmd) {
case 0x1:
- return SetNVMAPfd(input, output);
+ return WrapFixed(this, &nvhost_gpu::SetNVMAPfd, input, output);
case 0x3:
- return ChannelSetTimeout(input, output);
+ return WrapFixed(this, &nvhost_gpu::ChannelSetTimeout, input, output);
case 0x8:
- return SubmitGPFIFOBase(input, output, false);
+ return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, false);
case 0x9:
- return AllocateObjectContext(input, output);
+ return WrapFixed(this, &nvhost_gpu::AllocateObjectContext, input, output);
case 0xb:
- return ZCullBind(input, output);
+ return WrapFixed(this, &nvhost_gpu::ZCullBind, input, output);
case 0xc:
- return SetErrorNotifier(input, output);
+ return WrapFixed(this, &nvhost_gpu::SetErrorNotifier, input, output);
case 0xd:
- return SetChannelPriority(input, output);
+ return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output);
case 0x1a:
- return AllocGPFIFOEx2(input, output);
+ return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output);
case 0x1b:
- return SubmitGPFIFOBase(input, output, true);
+ return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true);
case 0x1d:
- return ChannelSetTimeslice(input, output);
+ return WrapFixed(this, &nvhost_gpu::ChannelSetTimeslice, input, output);
default:
break;
}
@@ -86,9 +87,9 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
case 'G':
switch (command.cmd) {
case 0x14:
- return SetClientData(input, output);
+ return WrapFixed(this, &nvhost_gpu::SetClientData, input, output);
case 0x15:
- return GetClientData(input, output);
+ return WrapFixed(this, &nvhost_gpu::GetClientData, input, output);
default:
break;
}
@@ -104,7 +105,8 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> inpu
case 'H':
switch (command.cmd) {
case 0x1b:
- return SubmitGPFIFOBase(input, inline_input, output);
+ return WrapFixedInlIn(this, &nvhost_gpu::SubmitGPFIFOBase2, input, inline_input,
+ output);
}
break;
}
@@ -121,63 +123,45 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
void nvhost_gpu::OnOpen(DeviceFD fd) {}
void nvhost_gpu::OnClose(DeviceFD fd) {}
-NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) {
- IoctlSetNvmapFD params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) {
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
nvmap_fd = params.nvmap_fd;
return NvResult::Success;
}
-NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_gpu::SetClientData(IoctlClientData& params) {
LOG_DEBUG(Service_NVDRV, "called");
-
- IoctlClientData params{};
- std::memcpy(&params, input.data(), input.size());
user_data = params.data;
return NvResult::Success;
}
-NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::span<u8> output) {
+NvResult nvhost_gpu::GetClientData(IoctlClientData& params) {
LOG_DEBUG(Service_NVDRV, "called");
-
- IoctlClientData params{};
- std::memcpy(&params, input.data(), input.size());
params.data = user_data;
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::span<u8> output) {
- std::memcpy(&zcull_params, input.data(), input.size());
+NvResult nvhost_gpu::ZCullBind(IoctlZCullBind& params) {
+ zcull_params = params;
LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va,
zcull_params.mode);
-
- std::memcpy(output.data(), &zcull_params, output.size());
return NvResult::Success;
}
-NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::span<u8> output) {
- IoctlSetErrorNotifier params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_gpu::SetErrorNotifier(IoctlSetErrorNotifier& params) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset,
params.size, params.mem);
-
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_gpu::SetChannelPriority(std::span<const u8> input, std::span<u8> output) {
- std::memcpy(&channel_priority, input.data(), input.size());
+NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) {
+ channel_priority = params.priority;
LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority);
-
return NvResult::Success;
}
-NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output) {
- IoctlAllocGpfifoEx2 params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) {
LOG_WARNING(Service_NVDRV,
"(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, "
"unk1={:X}, unk2={:X}, unk3={:X}",
@@ -193,18 +177,14 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> out
params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint);
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::span<u8> output) {
- IoctlAllocObjCtx params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_gpu::AllocateObjectContext(IoctlAllocObjCtx& params) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num,
params.flags);
params.obj_id = 0x0;
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
@@ -248,8 +228,7 @@ static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementW
return result;
}
-NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output,
- Tegra::CommandList&& entries) {
+NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries) {
LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address,
params.num_entries, params.flags.raw);
@@ -290,65 +269,55 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> o
flags.raw = 0;
- std::memcpy(output.data(), &params, sizeof(IoctlSubmitGpfifo));
return NvResult::Success;
}
-NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output,
- bool kickoff) {
- if (input.size() < sizeof(IoctlSubmitGpfifo)) {
+NvResult nvhost_gpu::SubmitGPFIFOBase1(IoctlSubmitGpfifo& params,
+ std::span<Tegra::CommandListHeader> commands, bool kickoff) {
+ if (params.num_entries > commands.size()) {
UNIMPLEMENTED();
return NvResult::InvalidSize;
}
- IoctlSubmitGpfifo params{};
- std::memcpy(&params, input.data(), sizeof(IoctlSubmitGpfifo));
- Tegra::CommandList entries(params.num_entries);
+ Tegra::CommandList entries(params.num_entries);
if (kickoff) {
system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(),
params.num_entries * sizeof(Tegra::CommandListHeader));
} else {
- std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)],
+ std::memcpy(entries.command_lists.data(), commands.data(),
params.num_entries * sizeof(Tegra::CommandListHeader));
}
- return SubmitGPFIFOImpl(params, output, std::move(entries));
+ return SubmitGPFIFOImpl(params, std::move(entries));
}
-NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline,
- std::span<u8> output) {
- if (input.size() < sizeof(IoctlSubmitGpfifo)) {
+NvResult nvhost_gpu::SubmitGPFIFOBase2(IoctlSubmitGpfifo& params,
+ std::span<const Tegra::CommandListHeader> commands) {
+ if (params.num_entries > commands.size()) {
UNIMPLEMENTED();
return NvResult::InvalidSize;
}
- IoctlSubmitGpfifo params{};
- std::memcpy(&params, input.data(), sizeof(IoctlSubmitGpfifo));
+
Tegra::CommandList entries(params.num_entries);
- std::memcpy(entries.command_lists.data(), input_inline.data(), input_inline.size());
- return SubmitGPFIFOImpl(params, output, std::move(entries));
+ std::memcpy(entries.command_lists.data(), commands.data(),
+ params.num_entries * sizeof(Tegra::CommandListHeader));
+ return SubmitGPFIFOImpl(params, std::move(entries));
}
-NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::span<u8> output) {
- IoctlGetWaitbase params{};
- std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
+NvResult nvhost_gpu::GetWaitbase(IoctlGetWaitbase& params) {
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
params.value = 0; // Seems to be hard coded at 0
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
-NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::span<u8> output) {
- IoctlChannelSetTimeout params{};
- std::memcpy(&params, input.data(), sizeof(IoctlChannelSetTimeout));
+NvResult nvhost_gpu::ChannelSetTimeout(IoctlChannelSetTimeout& params) {
LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout);
return NvResult::Success;
}
-NvResult nvhost_gpu::ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output) {
- IoctlSetTimeslice params{};
- std::memcpy(&params, input.data(), sizeof(IoctlSetTimeslice));
+NvResult nvhost_gpu::ChannelSetTimeslice(IoctlSetTimeslice& params) {
LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice);
channel_timeslice = params.timeslice;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index 529c20526..88fd228ff 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -186,23 +186,24 @@ private:
u32_le channel_priority{};
u32_le channel_timeslice{};
- NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output);
- NvResult SetClientData(std::span<const u8> input, std::span<u8> output);
- NvResult GetClientData(std::span<const u8> input, std::span<u8> output);
- NvResult ZCullBind(std::span<const u8> input, std::span<u8> output);
- NvResult SetErrorNotifier(std::span<const u8> input, std::span<u8> output);
- NvResult SetChannelPriority(std::span<const u8> input, std::span<u8> output);
- NvResult AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output);
- NvResult AllocateObjectContext(std::span<const u8> input, std::span<u8> output);
- NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output,
- Tegra::CommandList&& entries);
- NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output,
- bool kickoff = false);
- NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline,
- std::span<u8> output);
- NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output);
- NvResult ChannelSetTimeout(std::span<const u8> input, std::span<u8> output);
- NvResult ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output);
+ NvResult SetNVMAPfd(IoctlSetNvmapFD& params);
+ NvResult SetClientData(IoctlClientData& params);
+ NvResult GetClientData(IoctlClientData& params);
+ NvResult ZCullBind(IoctlZCullBind& params);
+ NvResult SetErrorNotifier(IoctlSetErrorNotifier& params);
+ NvResult SetChannelPriority(IoctlChannelSetPriority& params);
+ NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params);
+ NvResult AllocateObjectContext(IoctlAllocObjCtx& params);
+
+ NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries);
+ NvResult SubmitGPFIFOBase1(IoctlSubmitGpfifo& params,
+ std::span<Tegra::CommandListHeader> commands, bool kickoff = false);
+ NvResult SubmitGPFIFOBase2(IoctlSubmitGpfifo& params,
+ std::span<const Tegra::CommandListHeader> commands);
+
+ NvResult GetWaitbase(IoctlGetWaitbase& params);
+ NvResult ChannelSetTimeout(IoctlChannelSetTimeout& params);
+ NvResult ChannelSetTimeslice(IoctlSetTimeslice& params);
EventInterface& events_interface;
NvCore::Container& core;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index a174442a6..f43914e1b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -6,6 +6,7 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
#include "video_core/renderer_base.h"
@@ -25,18 +26,18 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
if (!host1x_file.fd_to_id.contains(fd)) {
host1x_file.fd_to_id[fd] = host1x_file.nvdec_next_id++;
}
- return Submit(fd, input, output);
+ return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd);
}
case 0x2:
- return GetSyncpoint(input, output);
+ return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output);
case 0x3:
- return GetWaitbase(input, output);
+ return WrapFixed(this, &nvhost_nvdec::GetWaitbase, input, output);
case 0x7:
- return SetSubmitTimeout(input, output);
+ return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output);
case 0x9:
- return MapBuffer(input, output);
+ return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output);
case 0xa:
- return UnmapBuffer(input, output);
+ return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output);
default:
break;
}
@@ -44,7 +45,7 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
case 'H':
switch (command.cmd) {
case 0x1:
- return SetNVMAPfd(input);
+ return WrapFixed(this, &nvhost_nvdec::SetNVMAPfd, input, output);
default:
break;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 61649aa4a..74c701b95 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -29,6 +29,9 @@ std::size_t SliceVectors(std::span<const u8> input, std::vector<T>& dst, std::si
return 0;
}
const size_t bytes_copied = count * sizeof(T);
+ if (input.size() < offset + bytes_copied) {
+ return 0;
+ }
std::memcpy(dst.data(), input.data() + offset, bytes_copied);
return bytes_copied;
}
@@ -41,6 +44,9 @@ std::size_t WriteVectors(std::span<u8> dst, const std::vector<T>& src, std::size
return 0;
}
const size_t bytes_copied = src.size() * sizeof(T);
+ if (dst.size() < offset + bytes_copied) {
+ return 0;
+ }
std::memcpy(dst.data() + offset, src.data(), bytes_copied);
return bytes_copied;
}
@@ -63,18 +69,14 @@ nvhost_nvdec_common::~nvhost_nvdec_common() {
core.Host1xDeviceFile().syncpts_accumulated.push_back(channel_syncpoint);
}
-NvResult nvhost_nvdec_common::SetNVMAPfd(std::span<const u8> input) {
- IoctlSetNvmapFD params{};
- std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
+NvResult nvhost_nvdec_common::SetNVMAPfd(IoctlSetNvmapFD& params) {
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
nvmap_fd = params.nvmap_fd;
return NvResult::Success;
}
-NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output) {
- IoctlSubmit params{};
- std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
+NvResult nvhost_nvdec_common::Submit(IoctlSubmit& params, std::span<u8> data, DeviceFD fd) {
LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count);
// Instantiate param buffers
@@ -85,12 +87,12 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std
std::vector<u32> fence_thresholds(params.fence_count);
// Slice input into their respective buffers
- std::size_t offset = sizeof(IoctlSubmit);
- offset += SliceVectors(input, command_buffers, params.cmd_buffer_count, offset);
- offset += SliceVectors(input, relocs, params.relocation_count, offset);
- offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset);
- offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset);
- offset += SliceVectors(input, fence_thresholds, params.fence_count, offset);
+ std::size_t offset = 0;
+ offset += SliceVectors(data, command_buffers, params.cmd_buffer_count, offset);
+ offset += SliceVectors(data, relocs, params.relocation_count, offset);
+ offset += SliceVectors(data, reloc_shifts, params.relocation_count, offset);
+ offset += SliceVectors(data, syncpt_increments, params.syncpoint_count, offset);
+ offset += SliceVectors(data, fence_thresholds, params.fence_count, offset);
auto& gpu = system.GPU();
if (gpu.UseNvdec()) {
@@ -108,72 +110,51 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std
cmdlist.size() * sizeof(u32));
gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist);
}
- std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
// Some games expect command_buffers to be written back
- offset = sizeof(IoctlSubmit);
- offset += WriteVectors(output, command_buffers, offset);
- offset += WriteVectors(output, relocs, offset);
- offset += WriteVectors(output, reloc_shifts, offset);
- offset += WriteVectors(output, syncpt_increments, offset);
- offset += WriteVectors(output, fence_thresholds, offset);
+ offset = 0;
+ offset += WriteVectors(data, command_buffers, offset);
+ offset += WriteVectors(data, relocs, offset);
+ offset += WriteVectors(data, reloc_shifts, offset);
+ offset += WriteVectors(data, syncpt_increments, offset);
+ offset += WriteVectors(data, fence_thresholds, offset);
return NvResult::Success;
}
-NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::span<u8> output) {
- IoctlGetSyncpoint params{};
- std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
+NvResult nvhost_nvdec_common::GetSyncpoint(IoctlGetSyncpoint& params) {
LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param);
-
- // const u32 id{NvCore::SyncpointManager::channel_syncpoints[static_cast<u32>(channel_type)]};
params.value = channel_syncpoint;
- std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
-
return NvResult::Success;
}
-NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::span<u8> output) {
- IoctlGetWaitbase params{};
+NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) {
LOG_CRITICAL(Service_NVDRV, "called WAITBASE");
- std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
params.value = 0; // Seems to be hard coded at 0
- std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
return NvResult::Success;
}
-NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::span<u8> output) {
- IoctlMapBuffer params{};
- std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
- std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
-
- SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
-
- for (auto& cmd_buffer : cmd_buffer_handles) {
- cmd_buffer.map_address = nvmap.PinHandle(cmd_buffer.map_handle);
+NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries) {
+ const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size()));
+ for (size_t i = 0; i < num_entries; i++) {
+ entries[i].map_address = nvmap.PinHandle(entries[i].map_handle);
}
- std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
- std::memcpy(output.data() + sizeof(IoctlMapBuffer), cmd_buffer_handles.data(),
- cmd_buffer_handles.size() * sizeof(MapBufferEntry));
return NvResult::Success;
}
-NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::span<u8> output) {
- IoctlMapBuffer params{};
- std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
- std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
-
- SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
- for (auto& cmd_buffer : cmd_buffer_handles) {
- nvmap.UnpinHandle(cmd_buffer.map_handle);
+NvResult nvhost_nvdec_common::UnmapBuffer(IoctlMapBuffer& params,
+ std::span<MapBufferEntry> entries) {
+ const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size()));
+ for (size_t i = 0; i < num_entries; i++) {
+ nvmap.UnpinHandle(entries[i].map_handle);
+ entries[i] = {};
}
- std::memset(output.data(), 0, output.size());
+ params = {};
return NvResult::Success;
}
-NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::span<u8> output) {
- std::memcpy(&submit_timeout, input.data(), input.size());
+NvResult nvhost_nvdec_common::SetSubmitTimeout(u32 timeout) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
return NvResult::Success;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 9bb573bfe..7ce748e18 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -107,13 +107,13 @@ protected:
static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size");
/// Ioctl command implementations
- NvResult SetNVMAPfd(std::span<const u8> input);
- NvResult Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output);
- NvResult GetSyncpoint(std::span<const u8> input, std::span<u8> output);
- NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output);
- NvResult MapBuffer(std::span<const u8> input, std::span<u8> output);
- NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output);
- NvResult SetSubmitTimeout(std::span<const u8> input, std::span<u8> output);
+ NvResult SetNVMAPfd(IoctlSetNvmapFD&);
+ NvResult Submit(IoctlSubmit& params, std::span<u8> input, DeviceFD fd);
+ NvResult GetSyncpoint(IoctlGetSyncpoint& params);
+ NvResult GetWaitbase(IoctlGetWaitbase& params);
+ NvResult MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries);
+ NvResult UnmapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries);
+ NvResult SetSubmitTimeout(u32 timeout);
Kernel::KEvent* QueryEvent(u32 event_id) override;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
index a05c8cdae..9e6b86458 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h"
namespace Service::Nvidia::Devices {
@@ -18,7 +19,7 @@ NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
case 'H':
switch (command.cmd) {
case 0x1:
- return SetNVMAPfd(input, output);
+ return WrapFixed(this, &nvhost_nvjpg::SetNVMAPfd, input, output);
default:
break;
}
@@ -46,9 +47,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in
void nvhost_nvjpg::OnOpen(DeviceFD fd) {}
void nvhost_nvjpg::OnClose(DeviceFD fd) {}
-NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) {
- IoctlSetNvmapFD params{};
- std::memcpy(&params, input.data(), input.size());
+NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) {
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
nvmap_fd = params.nvmap_fd;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
index 5623e0d47..790c97f6a 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
@@ -33,7 +33,7 @@ private:
s32_le nvmap_fd{};
- NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output);
+ NvResult SetNVMAPfd(IoctlSetNvmapFD& params);
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index c0b8684c3..87f8d7c22 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -5,6 +5,7 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_vic.h"
#include "video_core/renderer_base.h"
@@ -25,16 +26,16 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
if (!host1x_file.fd_to_id.contains(fd)) {
host1x_file.fd_to_id[fd] = host1x_file.vic_next_id++;
}
- return Submit(fd, input, output);
+ return WrapFixedVariable(this, &nvhost_vic::Submit, input, output, fd);
}
case 0x2:
- return GetSyncpoint(input, output);
+ return WrapFixed(this, &nvhost_vic::GetSyncpoint, input, output);
case 0x3:
- return GetWaitbase(input, output);
+ return WrapFixed(this, &nvhost_vic::GetWaitbase, input, output);
case 0x9:
- return MapBuffer(input, output);
+ return WrapFixedVariable(this, &nvhost_vic::MapBuffer, input, output);
case 0xa:
- return UnmapBuffer(input, output);
+ return WrapFixedVariable(this, &nvhost_vic::UnmapBuffer, input, output);
default:
break;
}
@@ -42,7 +43,7 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
case 'H':
switch (command.cmd) {
case 0x1:
- return SetNVMAPfd(input);
+ return WrapFixed(this, &nvhost_vic::SetNVMAPfd, input, output);
default:
break;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 968eaa175..71b2e62ec 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -13,6 +13,7 @@
#include "core/hle/kernel/k_process.h"
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/core/nvmap.h"
+#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
#include "core/memory.h"
@@ -31,17 +32,17 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
case 0x1:
switch (command.cmd) {
case 0x1:
- return IocCreate(input, output);
+ return WrapFixed(this, &nvmap::IocCreate, input, output);
case 0x3:
- return IocFromId(input, output);
+ return WrapFixed(this, &nvmap::IocFromId, input, output);
case 0x4:
- return IocAlloc(input, output);
+ return WrapFixed(this, &nvmap::IocAlloc, input, output);
case 0x5:
- return IocFree(input, output);
+ return WrapFixed(this, &nvmap::IocFree, input, output);
case 0x9:
- return IocParam(input, output);
+ return WrapFixed(this, &nvmap::IocParam, input, output);
case 0xe:
- return IocGetId(input, output);
+ return WrapFixed(this, &nvmap::IocGetId, input, output);
default:
break;
}
@@ -69,9 +70,7 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, st
void nvmap::OnOpen(DeviceFD fd) {}
void nvmap::OnClose(DeviceFD fd) {}
-NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) {
- IocCreateParams params;
- std::memcpy(&params, input.data(), sizeof(params));
+NvResult nvmap::IocCreate(IocCreateParams& params) {
LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size);
std::shared_ptr<NvCore::NvMap::Handle> handle_description{};
@@ -85,13 +84,10 @@ NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) {
params.handle = handle_description->id;
LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size);
- std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
-NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) {
- IocAllocParams params;
- std::memcpy(&params, input.data(), sizeof(params));
+NvResult nvmap::IocAlloc(IocAllocParams& params) {
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address);
if (!params.handle) {
@@ -133,14 +129,10 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) {
handle_description->size,
Kernel::KMemoryPermission::None, true, false)
.IsSuccess());
- std::memcpy(output.data(), &params, sizeof(params));
return result;
}
-NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) {
- IocGetIdParams params;
- std::memcpy(&params, input.data(), sizeof(params));
-
+NvResult nvmap::IocGetId(IocGetIdParams& params) {
LOG_DEBUG(Service_NVDRV, "called");
// See the comment in FromId for extra info on this function
@@ -157,14 +149,10 @@ NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) {
}
params.id = handle_description->id;
- std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
-NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) {
- IocFromIdParams params;
- std::memcpy(&params, input.data(), sizeof(params));
-
+NvResult nvmap::IocFromId(IocFromIdParams& params) {
LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id);
// Handles and IDs are always the same value in nvmap however IDs can be used globally given the
@@ -188,16 +176,12 @@ NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) {
return result;
}
params.handle = handle_description->id;
- std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
-NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) {
+NvResult nvmap::IocParam(IocParamParams& params) {
enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 };
- IocParamParams params;
- std::memcpy(&params, input.data(), sizeof(params));
-
LOG_DEBUG(Service_NVDRV, "called type={}", params.param);
if (!params.handle) {
@@ -237,14 +221,10 @@ NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) {
return NvResult::BadValue;
}
- std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
-NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) {
- IocFreeParams params;
- std::memcpy(&params, input.data(), sizeof(params));
-
+NvResult nvmap::IocFree(IocFreeParams& params) {
LOG_DEBUG(Service_NVDRV, "called");
if (!params.handle) {
@@ -267,7 +247,6 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) {
// This is possible when there's internal dups or other duplicates.
}
- std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index 4c0cc71cd..049c11028 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -99,12 +99,12 @@ public:
};
static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");
- NvResult IocCreate(std::span<const u8> input, std::span<u8> output);
- NvResult IocAlloc(std::span<const u8> input, std::span<u8> output);
- NvResult IocGetId(std::span<const u8> input, std::span<u8> output);
- NvResult IocFromId(std::span<const u8> input, std::span<u8> output);
- NvResult IocParam(std::span<const u8> input, std::span<u8> output);
- NvResult IocFree(std::span<const u8> input, std::span<u8> output);
+ NvResult IocCreate(IocCreateParams& params);
+ NvResult IocAlloc(IocAllocParams& params);
+ NvResult IocGetId(IocGetIdParams& params);
+ NvResult IocFromId(IocFromIdParams& params);
+ NvResult IocParam(IocParamParams& params);
+ NvResult IocFree(IocFreeParams& params);
private:
/// Id to use for the next handle that is created.
diff --git a/src/core/hle/service/nvnflinger/buffer_item.h b/src/core/hle/service/nvnflinger/buffer_item.h
index 3da8cc3aa..7fd808f54 100644
--- a/src/core/hle/service/nvnflinger/buffer_item.h
+++ b/src/core/hle/service/nvnflinger/buffer_item.h
@@ -15,7 +15,7 @@
namespace Service::android {
-struct GraphicBuffer;
+class GraphicBuffer;
class BufferItem final {
public:
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp
index 51291539d..d91886bed 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp
@@ -5,7 +5,6 @@
// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp
#include "common/logging/log.h"
-#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvnflinger/buffer_item.h"
#include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
#include "core/hle/service/nvnflinger/buffer_queue_core.h"
@@ -14,9 +13,8 @@
namespace Service::android {
-BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_,
- Service::Nvidia::NvCore::NvMap& nvmap_)
- : core{std::move(core_)}, slots{core->slots}, nvmap(nvmap_) {}
+BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_)
+ : core{std::move(core_)}, slots{core->slots} {}
BufferQueueConsumer::~BufferQueueConsumer() = default;
@@ -136,8 +134,6 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
slots[slot].buffer_state = BufferState::Free;
- nvmap.FreeHandle(slots[slot].graphic_buffer->BufferId(), true);
-
listener = core->connected_producer_listener;
LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot);
@@ -175,6 +171,25 @@ Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_
return Status::NoError;
}
+Status BufferQueueConsumer::Disconnect() {
+ LOG_DEBUG(Service_Nvnflinger, "called");
+
+ std::scoped_lock lock{core->mutex};
+
+ if (core->consumer_listener == nullptr) {
+ LOG_ERROR(Service_Nvnflinger, "no consumer is connected");
+ return Status::BadValue;
+ }
+
+ core->is_abandoned = true;
+ core->consumer_listener = nullptr;
+ core->queue.clear();
+ core->FreeAllBuffersLocked();
+ core->SignalDequeueCondition();
+
+ return Status::NoError;
+}
+
Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
if (out_slot_mask == nullptr) {
LOG_ERROR(Service_Nvnflinger, "out_slot_mask may not be nullptr");
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.h b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h
index 50ed0bb5f..0a61e8dbd 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.h
+++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h
@@ -13,10 +13,6 @@
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
#include "core/hle/service/nvnflinger/status.h"
-namespace Service::Nvidia::NvCore {
-class NvMap;
-} // namespace Service::Nvidia::NvCore
-
namespace Service::android {
class BufferItem;
@@ -25,19 +21,18 @@ class IConsumerListener;
class BufferQueueConsumer final {
public:
- explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_,
- Service::Nvidia::NvCore::NvMap& nvmap_);
+ explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
~BufferQueueConsumer();
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present);
Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence);
Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app);
+ Status Disconnect();
Status GetReleasedBuffers(u64* out_slot_mask);
private:
std::shared_ptr<BufferQueueCore> core;
BufferQueueDefs::SlotsType& slots;
- Service::Nvidia::NvCore::NvMap& nvmap;
};
} // namespace Service::android
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
index ed66f6f5b..4ed5e5978 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
@@ -14,24 +14,12 @@ BufferQueueCore::BufferQueueCore() = default;
BufferQueueCore::~BufferQueueCore() = default;
-void BufferQueueCore::NotifyShutdown() {
- std::scoped_lock lock{mutex};
-
- is_shutting_down = true;
-
- SignalDequeueCondition();
-}
-
void BufferQueueCore::SignalDequeueCondition() {
dequeue_possible.store(true);
dequeue_condition.notify_all();
}
bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock<std::mutex>& lk) {
- if (is_shutting_down) {
- return false;
- }
-
dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); });
dequeue_possible.store(false);
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.h b/src/core/hle/service/nvnflinger/buffer_queue_core.h
index 9164f08a0..e513d183b 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_core.h
+++ b/src/core/hle/service/nvnflinger/buffer_queue_core.h
@@ -34,8 +34,6 @@ public:
BufferQueueCore();
~BufferQueueCore();
- void NotifyShutdown();
-
private:
void SignalDequeueCondition();
bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk);
@@ -74,7 +72,6 @@ private:
u32 transform_hint{};
bool is_allocating{};
mutable std::condition_variable_any is_allocating_condition;
- bool is_shutting_down{};
};
} // namespace Service::android
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
index 6e7a49658..5d8762d25 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
@@ -13,7 +13,6 @@
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/hle_ipc.h"
#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvnflinger/buffer_queue_core.h"
#include "core/hle/service/nvnflinger/buffer_queue_producer.h"
#include "core/hle/service/nvnflinger/consumer_listener.h"
@@ -533,8 +532,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
item.is_droppable = core->dequeue_buffer_cannot_block || async;
item.swap_interval = swap_interval;
- nvmap.DuplicateHandle(item.graphic_buffer->BufferId(), true);
-
sticky_transform = sticky_transform_;
if (core->queue.empty()) {
@@ -744,19 +741,13 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
return Status::NoError;
}
- // HACK: We are not Android. Remove handle for items in queue, and clear queue.
- // Allows synchronous destruction of nvmap handles.
- for (auto& item : core->queue) {
- nvmap.FreeHandle(item.graphic_buffer->BufferId(), true);
- }
- core->queue.clear();
-
switch (api) {
case NativeWindowApi::Egl:
case NativeWindowApi::Cpu:
case NativeWindowApi::Media:
case NativeWindowApi::Camera:
if (core->connected_api == api) {
+ core->queue.clear();
core->FreeAllBuffersLocked();
core->connected_producer_listener = nullptr;
core->connected_api = NativeWindowApi::NoConnectedApi;
@@ -785,7 +776,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
}
Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
- const std::shared_ptr<GraphicBuffer>& buffer) {
+ const std::shared_ptr<NvGraphicBuffer>& buffer) {
LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
@@ -796,7 +787,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
slots[slot] = {};
slots[slot].fence = Fence::NoFence();
- slots[slot].graphic_buffer = buffer;
+ slots[slot].graphic_buffer = std::make_shared<GraphicBuffer>(nvmap, buffer);
slots[slot].frame_number = 0;
// Most games preallocate a buffer and pass a valid buffer here. However, it is possible for
@@ -839,7 +830,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u
}
case TransactionId::SetPreallocatedBuffer: {
const auto slot = parcel_in.Read<s32>();
- const auto buffer = parcel_in.ReadObject<GraphicBuffer>();
+ const auto buffer = parcel_in.ReadObject<NvGraphicBuffer>();
status = SetPreallocatedBuffer(slot, buffer);
break;
@@ -867,7 +858,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u
status = RequestBuffer(slot, &buf);
- parcel_out.WriteFlattenedObject(buf);
+ parcel_out.WriteFlattenedObject<NvGraphicBuffer>(buf.get());
break;
}
case TransactionId::QueueBuffer: {
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h
index d4201c104..64c17d56c 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h
+++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h
@@ -38,6 +38,7 @@ namespace Service::android {
class BufferQueueCore;
class IProducerListener;
+struct NvGraphicBuffer;
class BufferQueueProducer final : public IBinder {
public:
@@ -65,7 +66,7 @@ public:
bool producer_controlled_by_app, QueueBufferOutput* output);
Status Disconnect(NativeWindowApi api);
- Status SetPreallocatedBuffer(s32 slot, const std::shared_ptr<GraphicBuffer>& buffer);
+ Status SetPreallocatedBuffer(s32 slot, const std::shared_ptr<NvGraphicBuffer>& buffer);
private:
BufferQueueProducer(const BufferQueueProducer&) = delete;
diff --git a/src/core/hle/service/nvnflinger/buffer_slot.h b/src/core/hle/service/nvnflinger/buffer_slot.h
index d8c9dec3b..d25bca049 100644
--- a/src/core/hle/service/nvnflinger/buffer_slot.h
+++ b/src/core/hle/service/nvnflinger/buffer_slot.h
@@ -13,7 +13,7 @@
namespace Service::android {
-struct GraphicBuffer;
+class GraphicBuffer;
enum class BufferState : u32 {
Free = 0,
diff --git a/src/core/hle/service/nvnflinger/buffer_transform_flags.h b/src/core/hle/service/nvnflinger/buffer_transform_flags.h
index 67aa5dad6..ffe579718 100644
--- a/src/core/hle/service/nvnflinger/buffer_transform_flags.h
+++ b/src/core/hle/service/nvnflinger/buffer_transform_flags.h
@@ -3,6 +3,7 @@
#pragma once
+#include "common/common_funcs.h"
#include "common/common_types.h"
namespace Service::android {
@@ -21,5 +22,6 @@ enum class BufferTransformFlags : u32 {
/// Rotate source image 270 degrees clockwise
Rotate270 = 0x07,
};
+DECLARE_ENUM_FLAG_OPERATORS(BufferTransformFlags);
} // namespace Service::android
diff --git a/src/core/hle/service/nvnflinger/consumer_base.cpp b/src/core/hle/service/nvnflinger/consumer_base.cpp
index 4dcda8dac..1059e72bf 100644
--- a/src/core/hle/service/nvnflinger/consumer_base.cpp
+++ b/src/core/hle/service/nvnflinger/consumer_base.cpp
@@ -27,6 +27,26 @@ void ConsumerBase::Connect(bool controlled_by_app) {
consumer->Connect(shared_from_this(), controlled_by_app);
}
+void ConsumerBase::Abandon() {
+ LOG_DEBUG(Service_Nvnflinger, "called");
+
+ std::scoped_lock lock{mutex};
+
+ if (!is_abandoned) {
+ this->AbandonLocked();
+ is_abandoned = true;
+ }
+}
+
+void ConsumerBase::AbandonLocked() {
+ for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
+ this->FreeBufferLocked(i);
+ }
+ // disconnect from the BufferQueue
+ consumer->Disconnect();
+ consumer = nullptr;
+}
+
void ConsumerBase::FreeBufferLocked(s32 slot_index) {
LOG_DEBUG(Service_Nvnflinger, "slot_index={}", slot_index);
diff --git a/src/core/hle/service/nvnflinger/consumer_base.h b/src/core/hle/service/nvnflinger/consumer_base.h
index 264829414..ea3e9e97a 100644
--- a/src/core/hle/service/nvnflinger/consumer_base.h
+++ b/src/core/hle/service/nvnflinger/consumer_base.h
@@ -24,6 +24,7 @@ class BufferQueueConsumer;
class ConsumerBase : public IConsumerListener, public std::enable_shared_from_this<ConsumerBase> {
public:
void Connect(bool controlled_by_app);
+ void Abandon();
protected:
explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_);
@@ -34,6 +35,7 @@ protected:
void OnBuffersReleased() override;
void OnSidebandStreamChanged() override;
+ void AbandonLocked();
void FreeBufferLocked(s32 slot_index);
Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when);
Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer);
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp
index 2e29bc848..d7db24f42 100644
--- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp
+++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp
@@ -71,24 +71,17 @@ Result AllocateIoForProcessAddressSpace(Common::ProcessAddress* out_map_address,
R_SUCCEED();
}
-template <typename T>
-std::span<u8> SerializeIoc(T& params) {
- return std::span(reinterpret_cast<u8*>(std::addressof(params)), sizeof(T));
-}
-
Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, u32 size) {
// Create a handle.
- Nvidia::Devices::nvmap::IocCreateParams create_in_params{
+ Nvidia::Devices::nvmap::IocCreateParams create_params{
.size = size,
.handle = 0,
};
- Nvidia::Devices::nvmap::IocCreateParams create_out_params{};
- R_UNLESS(nvmap.IocCreate(SerializeIoc(create_in_params), SerializeIoc(create_out_params)) ==
- Nvidia::NvResult::Success,
+ R_UNLESS(nvmap.IocCreate(create_params) == Nvidia::NvResult::Success,
VI::ResultOperationFailed);
// Assign the output handle.
- *out_nv_map_handle = create_out_params.handle;
+ *out_nv_map_handle = create_params.handle;
// We succeeded.
R_SUCCEED();
@@ -96,13 +89,10 @@ Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap,
Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) {
// Free the handle.
- Nvidia::Devices::nvmap::IocFreeParams free_in_params{
+ Nvidia::Devices::nvmap::IocFreeParams free_params{
.handle = handle,
};
- Nvidia::Devices::nvmap::IocFreeParams free_out_params{};
- R_UNLESS(nvmap.IocFree(SerializeIoc(free_in_params), SerializeIoc(free_out_params)) ==
- Nvidia::NvResult::Success,
- VI::ResultOperationFailed);
+ R_UNLESS(nvmap.IocFree(free_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed);
// We succeeded.
R_SUCCEED();
@@ -111,7 +101,7 @@ Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) {
Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer,
u32 size) {
// Assign the allocated memory to the handle.
- Nvidia::Devices::nvmap::IocAllocParams alloc_in_params{
+ Nvidia::Devices::nvmap::IocAllocParams alloc_params{
.handle = handle,
.heap_mask = 0,
.flags = {},
@@ -119,10 +109,7 @@ Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::Proce
.kind = 0,
.address = GetInteger(buffer),
};
- Nvidia::Devices::nvmap::IocAllocParams alloc_out_params{};
- R_UNLESS(nvmap.IocAlloc(SerializeIoc(alloc_in_params), SerializeIoc(alloc_out_params)) ==
- Nvidia::NvResult::Success,
- VI::ResultOperationFailed);
+ R_UNLESS(nvmap.IocAlloc(alloc_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed);
// We succeeded.
R_SUCCEED();
@@ -179,7 +166,7 @@ constexpr SharedMemoryPoolLayout SharedBufferPoolLayout = [] {
}();
void MakeGraphicBuffer(android::BufferQueueProducer& producer, u32 slot, u32 handle) {
- auto buffer = std::make_shared<android::GraphicBuffer>();
+ auto buffer = std::make_shared<android::NvGraphicBuffer>();
buffer->width = SharedBufferWidth;
buffer->height = SharedBufferHeight;
buffer->stride = SharedBufferBlockLinearStride;
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index bebb45eae..0745434c5 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -47,7 +47,10 @@ void Nvnflinger::SplitVSync(std::stop_token stop_token) {
vsync_signal.Wait();
const auto lock_guard = Lock();
- Compose();
+
+ if (!is_abandoned) {
+ Compose();
+ }
}
}
@@ -98,7 +101,6 @@ Nvnflinger::~Nvnflinger() {
}
ShutdownLayers();
- vsync_thread = {};
if (nvdrv) {
nvdrv->Close(disp_fd);
@@ -106,12 +108,20 @@ Nvnflinger::~Nvnflinger() {
}
void Nvnflinger::ShutdownLayers() {
- const auto lock_guard = Lock();
- for (auto& display : displays) {
- for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
- display.GetLayer(layer).Core().NotifyShutdown();
+ // Abandon consumers.
+ {
+ const auto lock_guard = Lock();
+ for (auto& display : displays) {
+ for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
+ display.GetLayer(layer).GetConsumer().Abandon();
+ }
}
+
+ is_abandoned = true;
}
+
+ // Join the vsync thread, if it exists.
+ vsync_thread = {};
}
void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h
index 959d8b46b..f5d73acdb 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.h
+++ b/src/core/hle/service/nvnflinger/nvnflinger.h
@@ -140,6 +140,8 @@ private:
s32 swap_interval = 1;
+ bool is_abandoned = false;
+
/// Event that handles screen composition.
std::shared_ptr<Core::Timing::EventType> multi_composition_event;
std::shared_ptr<Core::Timing::EventType> single_composition_event;
diff --git a/src/core/hle/service/nvnflinger/status.h b/src/core/hle/service/nvnflinger/status.h
index 7af166c40..3fa0fe15b 100644
--- a/src/core/hle/service/nvnflinger/status.h
+++ b/src/core/hle/service/nvnflinger/status.h
@@ -19,7 +19,7 @@ enum class Status : s32 {
Busy = -16,
NoInit = -19,
BadValue = -22,
- InvalidOperation = -37,
+ InvalidOperation = -38,
BufferNeedsReallocation = 1,
ReleaseAllBuffers = 2,
};
diff --git a/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp b/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp
new file mode 100644
index 000000000..ce70946ec
--- /dev/null
+++ b/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp
@@ -0,0 +1,34 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/hle/service/nvdrv/core/nvmap.h"
+#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
+
+namespace Service::android {
+
+static NvGraphicBuffer GetBuffer(std::shared_ptr<NvGraphicBuffer>& buffer) {
+ if (buffer) {
+ return *buffer;
+ } else {
+ return {};
+ }
+}
+
+GraphicBuffer::GraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_)
+ : NvGraphicBuffer(width_, height_, format_, usage_), m_nvmap(nullptr) {}
+
+GraphicBuffer::GraphicBuffer(Service::Nvidia::NvCore::NvMap& nvmap,
+ std::shared_ptr<NvGraphicBuffer> buffer)
+ : NvGraphicBuffer(GetBuffer(buffer)), m_nvmap(std::addressof(nvmap)) {
+ if (this->BufferId() > 0) {
+ m_nvmap->DuplicateHandle(this->BufferId(), true);
+ }
+}
+
+GraphicBuffer::~GraphicBuffer() {
+ if (m_nvmap != nullptr && this->BufferId() > 0) {
+ m_nvmap->FreeHandle(this->BufferId(), true);
+ }
+}
+
+} // namespace Service::android
diff --git a/src/core/hle/service/nvnflinger/ui/graphic_buffer.h b/src/core/hle/service/nvnflinger/ui/graphic_buffer.h
index 3eac5cedd..da430aa75 100644
--- a/src/core/hle/service/nvnflinger/ui/graphic_buffer.h
+++ b/src/core/hle/service/nvnflinger/ui/graphic_buffer.h
@@ -6,16 +6,22 @@
#pragma once
+#include <memory>
+
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/service/nvnflinger/pixel_format.h"
+namespace Service::Nvidia::NvCore {
+class NvMap;
+} // namespace Service::Nvidia::NvCore
+
namespace Service::android {
-struct GraphicBuffer final {
- constexpr GraphicBuffer() = default;
+struct NvGraphicBuffer {
+ constexpr NvGraphicBuffer() = default;
- constexpr GraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_)
+ constexpr NvGraphicBuffer(u32 width_, u32 height_, PixelFormat format_, u32 usage_)
: width{static_cast<s32>(width_)}, height{static_cast<s32>(height_)}, format{format_},
usage{static_cast<s32>(usage_)} {}
@@ -93,6 +99,17 @@ struct GraphicBuffer final {
u32 offset{};
INSERT_PADDING_WORDS(60);
};
-static_assert(sizeof(GraphicBuffer) == 0x16C, "GraphicBuffer has wrong size");
+static_assert(sizeof(NvGraphicBuffer) == 0x16C, "NvGraphicBuffer has wrong size");
+
+class GraphicBuffer final : public NvGraphicBuffer {
+public:
+ explicit GraphicBuffer(u32 width, u32 height, PixelFormat format, u32 usage);
+ explicit GraphicBuffer(Service::Nvidia::NvCore::NvMap& nvmap,
+ std::shared_ptr<NvGraphicBuffer> buffer);
+ ~GraphicBuffer();
+
+private:
+ Service::Nvidia::NvCore::NvMap* m_nvmap{};
+};
} // namespace Service::android
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index ec3af80af..f5edfdc8b 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -19,19 +19,8 @@
namespace Service::Set {
-namespace {
-constexpr u64 SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET = 0x05;
-
-enum class GetFirmwareVersionType {
- Version1,
- Version2,
-};
-
-void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx,
- GetFirmwareVersionType type) {
- ASSERT_MSG(ctx.GetWriteBufferSize() == 0x100,
- "FirmwareVersion output buffer must be 0x100 bytes in size!");
-
+Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system,
+ GetFirmwareVersionType type) {
constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809;
auto& fsc = system.GetFileSystemController();
@@ -52,39 +41,34 @@ void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx,
FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId));
}
- const auto early_exit_failure = [&ctx](std::string_view desc, Result code) {
+ const auto early_exit_failure = [](std::string_view desc, Result code) {
LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).",
desc);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(code);
+ return code;
};
const auto ver_file = romfs->GetFile("file");
if (ver_file == nullptr) {
- early_exit_failure("The system version archive didn't contain the file 'file'.",
- FileSys::ERROR_INVALID_ARGUMENT);
- return;
+ return early_exit_failure("The system version archive didn't contain the file 'file'.",
+ FileSys::ERROR_INVALID_ARGUMENT);
}
auto data = ver_file->ReadAllBytes();
- if (data.size() != 0x100) {
- early_exit_failure("The system version file 'file' was not the correct size.",
- FileSys::ERROR_OUT_OF_BOUNDS);
- return;
+ if (data.size() != sizeof(FirmwareVersionFormat)) {
+ return early_exit_failure("The system version file 'file' was not the correct size.",
+ FileSys::ERROR_OUT_OF_BOUNDS);
}
+ std::memcpy(&out_firmware, data.data(), sizeof(FirmwareVersionFormat));
+
// If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will
// zero out the REVISION_MINOR field.
if (type == GetFirmwareVersionType::Version1) {
- data[SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET] = 0;
+ out_firmware.revision_minor = 0;
}
- ctx.WriteBuffer(data);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ return ResultSuccess;
}
-} // Anonymous namespace
void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
@@ -98,12 +82,32 @@ void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
- GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version1);
+
+ FirmwareVersionFormat firmware_data{};
+ const auto result =
+ GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version1);
+
+ if (result.IsSuccess()) {
+ ctx.WriteBuffer(firmware_data);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
}
void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
- GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version2);
+
+ FirmwareVersionFormat firmware_data{};
+ const auto result =
+ GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version2);
+
+ if (result.IsSuccess()) {
+ ctx.WriteBuffer(firmware_data);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
}
void SET_SYS::GetAccountSettings(HLERequestContext& ctx) {
@@ -431,8 +435,7 @@ void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {
void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) {
u8 battery_percentage_flag{1};
- LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}",
- battery_percentage_flag);
+ LOG_DEBUG(Service_SET, "(STUBBED) called, battery_percentage_flag={}", battery_percentage_flag);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
@@ -492,6 +495,29 @@ void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) {
rb.PushEnum(ChineseTraditionalInputMethod::Unknown0);
}
+void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_SET, "(STUBBED) called");
+
+ const HomeMenuScheme default_color = {
+ .main = 0xFF323232,
+ .back = 0xFF323232,
+ .sub = 0xFFFFFFFF,
+ .bezel = 0xFFFFFFFF,
+ .extra = 0xFF000000,
+ };
+
+ IPC::ResponseBuilder rb{ctx, 7};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(default_color);
+}
+
+void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) {
+ LOG_WARNING(Service_SET, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(0);
+}
void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
@@ -674,7 +700,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{171, nullptr, "SetChineseTraditionalInputMethod"},
{172, nullptr, "GetPtmCycleCountReliability"},
{173, nullptr, "SetPtmCycleCountReliability"},
- {174, nullptr, "GetHomeMenuScheme"},
+ {174, &SET_SYS::GetHomeMenuScheme, "GetHomeMenuScheme"},
{175, nullptr, "GetThemeSettings"},
{176, nullptr, "SetThemeSettings"},
{177, nullptr, "GetThemeKey"},
@@ -685,7 +711,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{182, nullptr, "SetT"},
{183, nullptr, "GetPlatformRegion"},
{184, nullptr, "SetPlatformRegion"},
- {185, nullptr, "GetHomeMenuSchemeModel"},
+ {185, &SET_SYS::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"},
{186, nullptr, "GetMemoryUsageRateFlag"},
{187, nullptr, "GetTouchScreenMode"},
{188, nullptr, "SetTouchScreenMode"},
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index c7dba2a9e..5f770fd32 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -4,6 +4,7 @@
#pragma once
#include "common/uuid.h"
+#include "core/hle/result.h"
#include "core/hle/service/service.h"
#include "core/hle/service/time/clock_types.h"
@@ -12,6 +13,29 @@ class System;
}
namespace Service::Set {
+enum class LanguageCode : u64;
+enum class GetFirmwareVersionType {
+ Version1,
+ Version2,
+};
+
+struct FirmwareVersionFormat {
+ u8 major;
+ u8 minor;
+ u8 micro;
+ INSERT_PADDING_BYTES(1);
+ u8 revision_major;
+ u8 revision_minor;
+ INSERT_PADDING_BYTES(2);
+ std::array<char, 0x20> platform;
+ std::array<u8, 0x40> version_hash;
+ std::array<char, 0x18> display_version;
+ std::array<char, 0x80> display_title;
+};
+static_assert(sizeof(FirmwareVersionFormat) == 0x100, "FirmwareVersionFormat is an invalid size");
+
+Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system,
+ GetFirmwareVersionType type);
class SET_SYS final : public ServiceFramework<SET_SYS> {
public:
@@ -269,6 +293,16 @@ private:
};
static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size");
+ /// This is nn::settings::system::HomeMenuScheme
+ struct HomeMenuScheme {
+ u32 main;
+ u32 back;
+ u32 sub;
+ u32 bezel;
+ u32 extra;
+ };
+ static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size");
+
void SetLanguageCode(HLERequestContext& ctx);
void GetFirmwareVersion(HLERequestContext& ctx);
void GetFirmwareVersion2(HLERequestContext& ctx);
@@ -305,6 +339,8 @@ private:
void GetKeyboardLayout(HLERequestContext& ctx);
void GetChineseTraditionalInputMethod(HLERequestContext& ctx);
void GetFieldTestingFlag(HLERequestContext& ctx);
+ void GetHomeMenuScheme(HLERequestContext& ctx);
+ void GetHomeMenuSchemeModel(HLERequestContext& ctx);
AccountSettings account_settings{
.flags = {},
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 85849d5f3..dd652ca42 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -39,6 +39,18 @@ bool IsConnectionBased(Type type) {
}
}
+template <typename T>
+T GetValue(std::span<const u8> buffer) {
+ T t{};
+ std::memcpy(&t, buffer.data(), std::min(sizeof(T), buffer.size()));
+ return t;
+}
+
+template <typename T>
+void PutValue(std::span<u8> buffer, const T& t) {
+ std::memcpy(buffer.data(), &t, std::min(sizeof(T), buffer.size()));
+}
+
} // Anonymous namespace
void BSD::PollWork::Execute(BSD* bsd) {
@@ -316,22 +328,12 @@ void BSD::SetSockOpt(HLERequestContext& ctx) {
const s32 fd = rp.Pop<s32>();
const u32 level = rp.Pop<u32>();
const OptName optname = static_cast<OptName>(rp.Pop<u32>());
-
- const auto buffer = ctx.ReadBuffer();
- const u8* optval = buffer.empty() ? nullptr : buffer.data();
- size_t optlen = buffer.size();
-
- std::array<u64, 2> values;
- if ((optname == OptName::SNDTIMEO || optname == OptName::RCVTIMEO) && buffer.size() == 8) {
- std::memcpy(values.data(), buffer.data(), sizeof(values));
- optlen = sizeof(values);
- optval = reinterpret_cast<const u8*>(values.data());
- }
+ const auto optval = ctx.ReadBuffer();
LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level,
- static_cast<u32>(optname), optlen);
+ static_cast<u32>(optname), optval.size());
- BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optlen, optval));
+ BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval));
}
void BSD::Shutdown(HLERequestContext& ctx) {
@@ -521,18 +523,19 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco
std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
s32 nfds, s32 timeout) {
- if (write_buffer.size() < nfds * sizeof(PollFD)) {
- return {-1, Errno::INVAL};
- }
-
- if (nfds == 0) {
+ if (nfds <= 0) {
// When no entries are provided, -1 is returned with errno zero
return {-1, Errno::SUCCESS};
}
+ if (read_buffer.size() < nfds * sizeof(PollFD)) {
+ return {-1, Errno::INVAL};
+ }
+ if (write_buffer.size() < nfds * sizeof(PollFD)) {
+ return {-1, Errno::INVAL};
+ }
- const size_t length = std::min(read_buffer.size(), write_buffer.size());
std::vector<PollFD> fds(nfds);
- std::memcpy(fds.data(), read_buffer.data(), length);
+ std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(PollFD));
if (timeout >= 0) {
const s64 seconds = timeout / 1000;
@@ -580,7 +583,7 @@ std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<con
for (size_t i = 0; i < num; ++i) {
fds[i].revents = Translate(host_pollfds[i].revents);
}
- std::memcpy(write_buffer.data(), fds.data(), length);
+ std::memcpy(write_buffer.data(), fds.data(), nfds * sizeof(PollFD));
return Translate(result);
}
@@ -608,8 +611,7 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
new_descriptor.is_connection_based = descriptor.is_connection_based;
const SockAddrIn guest_addr_in = Translate(result.sockaddr_in);
- const size_t length = std::min(sizeof(guest_addr_in), write_buffer.size());
- std::memcpy(write_buffer.data(), &guest_addr_in, length);
+ PutValue(write_buffer, guest_addr_in);
return {new_fd, Errno::SUCCESS};
}
@@ -619,8 +621,7 @@ Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
return Errno::BADF;
}
ASSERT(addr.size() == sizeof(SockAddrIn));
- SockAddrIn addr_in;
- std::memcpy(&addr_in, addr.data(), sizeof(addr_in));
+ auto addr_in = GetValue<SockAddrIn>(addr);
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
}
@@ -631,8 +632,7 @@ Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
}
UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn));
- SockAddrIn addr_in;
- std::memcpy(&addr_in, addr.data(), sizeof(addr_in));
+ auto addr_in = GetValue<SockAddrIn>(addr);
return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
}
@@ -650,7 +650,7 @@ Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
ASSERT(write_buffer.size() >= sizeof(guest_addrin));
write_buffer.resize(sizeof(guest_addrin));
- std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin));
+ PutValue(write_buffer, guest_addrin);
return Translate(bsd_errno);
}
@@ -667,7 +667,7 @@ Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
ASSERT(write_buffer.size() >= sizeof(guest_addrin));
write_buffer.resize(sizeof(guest_addrin));
- std::memcpy(write_buffer.data(), &guest_addrin, sizeof(guest_addrin));
+ PutValue(write_buffer, guest_addrin);
return Translate(bsd_errno);
}
@@ -725,7 +725,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o
optval.size() == sizeof(Errno), { return Errno::INVAL; },
"Incorrect getsockopt option size");
optval.resize(sizeof(Errno));
- memcpy(optval.data(), &translated_pending_err, sizeof(Errno));
+ PutValue(optval, translated_pending_err);
}
return Translate(getsockopt_err);
}
@@ -735,7 +735,7 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& o
}
}
-Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval) {
+Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
if (!IsFileDescriptorValid(fd)) {
return Errno::BADF;
}
@@ -748,17 +748,15 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, con
Network::SocketBase* const socket = file_descriptors[fd]->socket.get();
if (optname == OptName::LINGER) {
- ASSERT(optlen == sizeof(Linger));
- Linger linger;
- std::memcpy(&linger, optval, sizeof(linger));
+ ASSERT(optval.size() == sizeof(Linger));
+ auto linger = GetValue<Linger>(optval);
ASSERT(linger.onoff == 0 || linger.onoff == 1);
return Translate(socket->SetLinger(linger.onoff != 0, linger.linger));
}
- ASSERT(optlen == sizeof(u32));
- u32 value;
- std::memcpy(&value, optval, sizeof(value));
+ ASSERT(optval.size() == sizeof(u32));
+ auto value = GetValue<u32>(optval);
switch (optname) {
case OptName::REUSEADDR:
@@ -862,7 +860,7 @@ std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& mess
} else {
ASSERT(addr.size() == sizeof(SockAddrIn));
const SockAddrIn result = Translate(addr_in);
- std::memcpy(addr.data(), &result, sizeof(result));
+ PutValue(addr, result);
}
}
@@ -886,8 +884,7 @@ std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> mes
Network::SockAddrIn* p_addr_in = nullptr;
if (!addr.empty()) {
ASSERT(addr.size() == sizeof(SockAddrIn));
- SockAddrIn guest_addr_in;
- std::memcpy(&guest_addr_in, addr.data(), sizeof(guest_addr_in));
+ auto guest_addr_in = GetValue<SockAddrIn>(addr);
addr_in = Translate(guest_addr_in);
p_addr_in = &addr_in;
}
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 161f22b9b..4f69d382c 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -163,7 +163,7 @@ private:
Errno ListenImpl(s32 fd, s32 backlog);
std::pair<s32, Errno> FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg);
Errno GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval);
- Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, const void* optval);
+ Errno SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval);
Errno ShutdownImpl(s32 fd, s32 how);
std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message);
std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h
index 9fc01ea90..7149fffeb 100644
--- a/src/core/hle/service/time/clock_types.h
+++ b/src/core/hle/service/time/clock_types.h
@@ -11,6 +11,11 @@
#include "core/hle/service/time/errors.h"
#include "core/hle/service/time/time_zone_types.h"
+// Defined by WinBase.h on Windows
+#ifdef GetCurrentTime
+#undef GetCurrentTime
+#endif
+
namespace Service::Time::Clock {
enum class TimeType : u8 {
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index f0b5eff8a..d30f49877 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -35,7 +35,7 @@ static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_cont
return {
buffer_queue_core,
std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core, nvmap),
- std::make_unique<android::BufferQueueConsumer>(buffer_queue_core, nvmap)};
+ std::make_unique<android::BufferQueueConsumer>(buffer_queue_core)};
}
Display::Display(u64 id, std::string name_,
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index fa5273402..a3431772a 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -1,8 +1,10 @@
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
+// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <cstring>
+#include <mutex>
#include <span>
#include "common/assert.h"
@@ -10,6 +12,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/page_table.h"
+#include "common/scope_exit.h"
#include "common/settings.h"
#include "common/swap.h"
#include "core/core.h"
@@ -41,7 +44,7 @@ struct Memory::Impl {
explicit Impl(Core::System& system_) : system{system_} {}
void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
- current_page_table = &process.GetPageTable().PageTableImpl();
+ current_page_table = &process.GetPageTable().GetImpl();
current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
const std::size_t address_space_width = process.GetPageTable().GetAddressSpaceWidth();
@@ -195,7 +198,7 @@ struct Memory::Impl {
bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
auto on_memory, auto on_rasterizer, auto increment) {
- const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl();
+ const auto& page_table = system.ApplicationProcess()->GetPageTable().GetImpl();
std::size_t remaining_size = size;
std::size_t page_index = addr >> YUZU_PAGEBITS;
std::size_t page_offset = addr & YUZU_PAGEMASK;
@@ -318,7 +321,7 @@ struct Memory::Impl {
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) {
if constexpr (!UNSAFE) {
- system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
+ HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
}
std::memcpy(host_ptr, src_buffer, copy_amount);
},
@@ -351,7 +354,7 @@ struct Memory::Impl {
},
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) {
- system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
+ HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
std::memset(host_ptr, 0, copy_amount);
},
[](const std::size_t copy_amount) {});
@@ -420,7 +423,7 @@ struct Memory::Impl {
const std::size_t block_size) {
// dc cvac: Store to point of coherency
// CPU flush -> GPU invalidate
- system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
+ HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
};
return PerformCacheOperation(dest_addr, size, on_rasterizer);
}
@@ -430,7 +433,7 @@ struct Memory::Impl {
const std::size_t block_size) {
// dc civac: Store to point of coherency, and invalidate from cache
// CPU flush -> GPU invalidate
- system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
+ HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
};
return PerformCacheOperation(dest_addr, size, on_rasterizer);
}
@@ -767,7 +770,18 @@ struct Memory::Impl {
}
void HandleRasterizerWrite(VAddr address, size_t size) {
- const size_t core = system.GetCurrentHostThreadID();
+ constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
+ const size_t core = std::min(system.GetCurrentHostThreadID(),
+ sys_core); // any other calls threads go to syscore.
+ // Guard on sys_core;
+ if (core == sys_core) [[unlikely]] {
+ sys_core_guard.lock();
+ }
+ SCOPE_EXIT({
+ if (core == sys_core) [[unlikely]] {
+ sys_core_guard.unlock();
+ }
+ });
auto& current_area = rasterizer_write_areas[core];
VAddr subaddress = address >> YUZU_PAGEBITS;
bool do_collection = current_area.last_address == subaddress;
@@ -799,6 +813,7 @@ struct Memory::Impl {
rasterizer_read_areas{};
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
+ std::mutex sys_core_guard;
};
Memory::Memory(Core::System& system_) : system{system_} {
@@ -826,7 +841,7 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
const Kernel::KProcess& process = *system.ApplicationProcess();
- const auto& page_table = process.GetPageTable().PageTableImpl();
+ const auto& page_table = process.GetPageTable().GetImpl();
const size_t page = vaddr >> YUZU_PAGEBITS;
if (page >= page_table.pointers.size()) {
return false;
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 53a89cc8f..db30ba598 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -10,7 +10,8 @@
#include "core/hle/kernel/k_page_table.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/hid.h"
+#include "core/hle/service/hid/hid_server.h"
+#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/sm/sm.h"
#include "core/memory.h"
#include "core/memory/cheat_engine.h"
@@ -54,23 +55,20 @@ void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size)
}
u64 StandardVmCallbacks::HidKeysDown() {
- const auto hid = system.ServiceManager().GetService<Service::HID::Hid>("hid");
+ const auto hid = system.ServiceManager().GetService<Service::HID::IHidServer>("hid");
if (hid == nullptr) {
LOG_WARNING(CheatEngine, "Attempted to read input state, but hid is not initialized!");
return 0;
}
- const auto applet_resource = hid->GetAppletResource();
+ const auto applet_resource = hid->GetResourceManager();
if (applet_resource == nullptr) {
LOG_WARNING(CheatEngine,
"Attempted to read input state, but applet resource is not initialized!");
return 0;
}
- const auto press_state =
- applet_resource
- ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)
- .GetAndResetPressState();
+ const auto press_state = applet_resource->GetNpad()->GetAndResetPressState();
return static_cast<u64>(press_state & HID::NpadButton::All);
}
diff --git a/src/frontend_common/CMakeLists.txt b/src/frontend_common/CMakeLists.txt
new file mode 100644
index 000000000..22e9337c4
--- /dev/null
+++ b/src/frontend_common/CMakeLists.txt
@@ -0,0 +1,10 @@
+# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+add_library(frontend_common STATIC
+ config.cpp
+ config.h
+)
+
+create_target_directory_groups(frontend_common)
+target_link_libraries(frontend_common PUBLIC core SimpleIni::SimpleIni PRIVATE common Boost::headers)
diff --git a/src/frontend_common/config.cpp b/src/frontend_common/config.cpp
new file mode 100644
index 000000000..7474cb0f9
--- /dev/null
+++ b/src/frontend_common/config.cpp
@@ -0,0 +1,1008 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <algorithm>
+#include <array>
+#include "common/fs/fs.h"
+#include "common/fs/path_util.h"
+#include "common/settings.h"
+#include "common/settings_common.h"
+#include "common/settings_enums.h"
+#include "config.h"
+#include "core/core.h"
+#include "core/hle/service/acc/profile_manager.h"
+#include "core/hle/service/hid/controllers/npad.h"
+#include "network/network.h"
+
+#include <boost/algorithm/string/replace.hpp>
+
+#include "common/string_util.h"
+
+namespace FS = Common::FS;
+
+Config::Config(const ConfigType config_type)
+ : type(config_type), global{config_type == ConfigType::GlobalConfig} {}
+
+void Config::Initialize(const std::string& config_name) {
+ const std::filesystem::path fs_config_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir);
+ const auto config_file = fmt::format("{}.ini", config_name);
+
+ switch (type) {
+ case ConfigType::GlobalConfig:
+ config_loc = FS::PathToUTF8String(fs_config_loc / config_file);
+ void(FS::CreateParentDir(config_loc));
+ SetUpIni();
+ Reload();
+ break;
+ case ConfigType::PerGameConfig:
+ config_loc = FS::PathToUTF8String(fs_config_loc / "custom" / FS::ToU8String(config_file));
+ void(FS::CreateParentDir(config_loc));
+ SetUpIni();
+ Reload();
+ break;
+ case ConfigType::InputProfile:
+ config_loc = FS::PathToUTF8String(fs_config_loc / "input" / config_file);
+ void(FS::CreateParentDir(config_loc));
+ SetUpIni();
+ break;
+ }
+}
+
+void Config::Initialize(const std::optional<std::string> config_path) {
+ const std::filesystem::path default_sdl_config_path =
+ FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "sdl2-config.ini";
+ config_loc = config_path.value_or(FS::PathToUTF8String(default_sdl_config_path));
+ void(FS::CreateParentDir(config_loc));
+ SetUpIni();
+ Reload();
+}
+
+void Config::WriteToIni() const {
+ FILE* fp = nullptr;
+#ifdef _WIN32
+ fp = _wfopen(Common::UTF8ToUTF16W(config_loc).data(), L"wb");
+#else
+ fp = fopen(config_loc.c_str(), "wb");
+#endif
+
+ if (fp == nullptr) {
+ LOG_ERROR(Frontend, "Config file could not be saved!");
+ return;
+ }
+
+ CSimpleIniA::FileWriter writer(fp);
+ const SI_Error rc = config->Save(writer, false);
+ if (rc < 0) {
+ LOG_ERROR(Frontend, "Config file could not be saved!");
+ }
+ fclose(fp);
+}
+
+void Config::SetUpIni() {
+ config = std::make_unique<CSimpleIniA>();
+ config->SetUnicode(true);
+ config->SetSpaces(false);
+
+ FILE* fp = nullptr;
+#ifdef _WIN32
+ _wfopen_s(&fp, Common::UTF8ToUTF16W(config_loc).data(), L"rb, ccs=UTF-8");
+ if (fp == nullptr) {
+ fp = _wfopen(Common::UTF8ToUTF16W(config_loc).data(), L"wb, ccs=UTF-8");
+ }
+#else
+ fp = fopen(config_loc.c_str(), "rb");
+ if (fp == nullptr) {
+ fp = fopen(config_loc.c_str(), "wb");
+ }
+#endif
+
+ if (fp == nullptr) {
+ LOG_ERROR(Frontend, "Config file could not be loaded!");
+ return;
+ }
+
+ if (SI_Error rc = config->LoadFile(fp); rc < 0) {
+ LOG_ERROR(Frontend, "Config file could not be loaded!");
+ }
+ fclose(fp);
+}
+
+bool Config::IsCustomConfig() const {
+ return type == ConfigType::PerGameConfig;
+}
+
+void Config::ReadPlayerValues(const std::size_t player_index) {
+ std::string player_prefix;
+ if (type != ConfigType::InputProfile) {
+ player_prefix.append("player_").append(ToString(player_index)).append("_");
+ }
+
+ auto& player = Settings::values.players.GetValue()[player_index];
+ if (IsCustomConfig()) {
+ const auto profile_name =
+ ReadStringSetting(std::string(player_prefix).append("profile_name"));
+ if (profile_name.empty()) {
+ // Use the global input config
+ player = Settings::values.players.GetValue(true)[player_index];
+ return;
+ }
+ player.profile_name = profile_name;
+ }
+
+ if (player_prefix.empty() && Settings::IsConfiguringGlobal()) {
+ const auto controller = static_cast<Settings::ControllerType>(
+ ReadIntegerSetting(std::string(player_prefix).append("type"),
+ static_cast<u8>(Settings::ControllerType::ProController)));
+
+ if (controller == Settings::ControllerType::LeftJoycon ||
+ controller == Settings::ControllerType::RightJoycon) {
+ player.controller_type = controller;
+ }
+ } else {
+ std::string connected_key = player_prefix;
+ player.connected = ReadBooleanSetting(connected_key.append("connected"),
+ std::make_optional(player_index == 0));
+
+ player.controller_type = static_cast<Settings::ControllerType>(
+ ReadIntegerSetting(std::string(player_prefix).append("type"),
+ static_cast<u8>(Settings::ControllerType::ProController)));
+
+ player.vibration_enabled = ReadBooleanSetting(
+ std::string(player_prefix).append("vibration_enabled"), std::make_optional(true));
+
+ player.vibration_strength = static_cast<int>(
+ ReadIntegerSetting(std::string(player_prefix).append("vibration_strength"), 100));
+
+ player.body_color_left = static_cast<u32>(ReadIntegerSetting(
+ std::string(player_prefix).append("body_color_left"), Settings::JOYCON_BODY_NEON_BLUE));
+ player.body_color_right = static_cast<u32>(ReadIntegerSetting(
+ std::string(player_prefix).append("body_color_right"), Settings::JOYCON_BODY_NEON_RED));
+ player.button_color_left = static_cast<u32>(
+ ReadIntegerSetting(std::string(player_prefix).append("button_color_left"),
+ Settings::JOYCON_BUTTONS_NEON_BLUE));
+ player.button_color_right = static_cast<u32>(
+ ReadIntegerSetting(std::string(player_prefix).append("button_color_right"),
+ Settings::JOYCON_BUTTONS_NEON_RED));
+ }
+}
+
+void Config::ReadTouchscreenValues() {
+ Settings::values.touchscreen.enabled =
+ ReadBooleanSetting(std::string("touchscreen_enabled"), std::make_optional(true));
+ Settings::values.touchscreen.rotation_angle =
+ static_cast<u32>(ReadIntegerSetting(std::string("touchscreen_angle"), 0));
+ Settings::values.touchscreen.diameter_x =
+ static_cast<u32>(ReadIntegerSetting(std::string("touchscreen_diameter_x"), 15));
+ Settings::values.touchscreen.diameter_y =
+ static_cast<u32>(ReadIntegerSetting(std::string("touchscreen_diameter_y"), 15));
+}
+
+void Config::ReadAudioValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Audio));
+
+ ReadCategory(Settings::Category::Audio);
+ ReadCategory(Settings::Category::UiAudio);
+
+ EndGroup();
+}
+
+void Config::ReadControlValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ ReadCategory(Settings::Category::Controls);
+
+ Settings::values.players.SetGlobal(!IsCustomConfig());
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
+ ReadPlayerValues(p);
+ }
+
+ // Disable docked mode if handheld is selected
+ const auto controller_type = Settings::values.players.GetValue()[0].controller_type;
+ if (controller_type == Settings::ControllerType::Handheld) {
+ Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig());
+ Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld);
+ }
+
+ if (IsCustomConfig()) {
+ EndGroup();
+ return;
+ }
+ ReadTouchscreenValues();
+ ReadMotionTouchValues();
+
+ EndGroup();
+}
+
+void Config::ReadMotionTouchValues() {
+ int num_touch_from_button_maps = BeginArray(std::string("touch_from_button_maps"));
+
+ if (num_touch_from_button_maps > 0) {
+ for (int i = 0; i < num_touch_from_button_maps; ++i) {
+ SetArrayIndex(i);
+
+ Settings::TouchFromButtonMap map;
+ map.name = ReadStringSetting(std::string("name"), std::string("default"));
+
+ const int num_touch_maps = BeginArray(std::string("entries"));
+ map.buttons.reserve(num_touch_maps);
+ for (int j = 0; j < num_touch_maps; j++) {
+ SetArrayIndex(j);
+ std::string touch_mapping = ReadStringSetting(std::string("bind"));
+ map.buttons.emplace_back(std::move(touch_mapping));
+ }
+ EndArray(); // entries
+ Settings::values.touch_from_button_maps.emplace_back(std::move(map));
+ }
+ } else {
+ Settings::values.touch_from_button_maps.emplace_back(
+ Settings::TouchFromButtonMap{"default", {}});
+ num_touch_from_button_maps = 1;
+ }
+ EndArray(); // touch_from_button_maps
+
+ Settings::values.touch_from_button_map_index = std::clamp(
+ Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
+}
+
+void Config::ReadCoreValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Core));
+
+ ReadCategory(Settings::Category::Core);
+
+ EndGroup();
+}
+
+void Config::ReadDataStorageValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
+
+ FS::SetYuzuPath(FS::YuzuPath::NANDDir, ReadStringSetting(std::string("nand_directory")));
+ FS::SetYuzuPath(FS::YuzuPath::SDMCDir, ReadStringSetting(std::string("sdmc_directory")));
+ FS::SetYuzuPath(FS::YuzuPath::LoadDir, ReadStringSetting(std::string("load_directory")));
+ FS::SetYuzuPath(FS::YuzuPath::DumpDir, ReadStringSetting(std::string("dump_directory")));
+ FS::SetYuzuPath(FS::YuzuPath::TASDir, ReadStringSetting(std::string("tas_directory")));
+
+ ReadCategory(Settings::Category::DataStorage);
+
+ EndGroup();
+}
+
+void Config::ReadDebuggingValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Debugging));
+
+ // Intentionally not using the QT default setting as this is intended to be changed in the ini
+ Settings::values.record_frame_times =
+ ReadBooleanSetting(std::string("record_frame_times"), std::make_optional(false));
+
+ ReadCategory(Settings::Category::Debugging);
+ ReadCategory(Settings::Category::DebuggingGraphics);
+
+ EndGroup();
+}
+
+void Config::ReadServiceValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Services));
+
+ ReadCategory(Settings::Category::Services);
+
+ EndGroup();
+}
+
+void Config::ReadDisabledAddOnValues() {
+ // Custom config section
+ BeginGroup(std::string("DisabledAddOns"));
+
+ const int size = BeginArray(std::string(""));
+ for (int i = 0; i < size; ++i) {
+ SetArrayIndex(i);
+ const auto title_id = ReadUnsignedIntegerSetting(std::string("title_id"), 0);
+ std::vector<std::string> out;
+ const int d_size = BeginArray("disabled");
+ for (int j = 0; j < d_size; ++j) {
+ SetArrayIndex(j);
+ out.push_back(ReadStringSetting(std::string("d"), std::string("")));
+ }
+ EndArray(); // d
+ Settings::values.disabled_addons.insert_or_assign(title_id, out);
+ }
+ EndArray(); // Base disabled addons array - Has no base key
+
+ EndGroup();
+}
+
+void Config::ReadMiscellaneousValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Miscellaneous));
+
+ ReadCategory(Settings::Category::Miscellaneous);
+
+ EndGroup();
+}
+
+void Config::ReadCpuValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Cpu));
+
+ ReadCategory(Settings::Category::Cpu);
+ ReadCategory(Settings::Category::CpuDebug);
+ ReadCategory(Settings::Category::CpuUnsafe);
+
+ EndGroup();
+}
+
+void Config::ReadRendererValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Renderer));
+
+ ReadCategory(Settings::Category::Renderer);
+ ReadCategory(Settings::Category::RendererAdvanced);
+ ReadCategory(Settings::Category::RendererDebug);
+
+ EndGroup();
+}
+
+void Config::ReadScreenshotValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Screenshots));
+
+ ReadCategory(Settings::Category::Screenshots);
+ FS::SetYuzuPath(FS::YuzuPath::ScreenshotsDir,
+ ReadStringSetting(std::string("screenshot_path")));
+
+ EndGroup();
+}
+
+void Config::ReadSystemValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::System));
+
+ ReadCategory(Settings::Category::System);
+ ReadCategory(Settings::Category::SystemAudio);
+
+ EndGroup();
+}
+
+void Config::ReadWebServiceValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::WebService));
+
+ ReadCategory(Settings::Category::WebService);
+
+ EndGroup();
+}
+
+void Config::ReadNetworkValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Services));
+
+ ReadCategory(Settings::Category::Network);
+
+ EndGroup();
+}
+
+void Config::ReadValues() {
+ if (global) {
+ ReadDataStorageValues();
+ ReadDebuggingValues();
+ ReadDisabledAddOnValues();
+ ReadNetworkValues();
+ ReadServiceValues();
+ ReadWebServiceValues();
+ ReadMiscellaneousValues();
+ }
+ ReadControlValues();
+ ReadCoreValues();
+ ReadCpuValues();
+ ReadRendererValues();
+ ReadAudioValues();
+ ReadSystemValues();
+}
+
+void Config::SavePlayerValues(const std::size_t player_index) {
+ std::string player_prefix;
+ if (type != ConfigType::InputProfile) {
+ player_prefix = std::string("player_").append(ToString(player_index)).append("_");
+ }
+
+ const auto& player = Settings::values.players.GetValue()[player_index];
+ if (IsCustomConfig()) {
+ if (player.profile_name.empty()) {
+ // No custom profile selected
+ return;
+ }
+ WriteSetting(std::string(player_prefix).append("profile_name"), player.profile_name,
+ std::make_optional(std::string("")));
+ }
+
+ WriteSetting(std::string(player_prefix).append("type"), static_cast<u8>(player.controller_type),
+ std::make_optional(static_cast<u8>(Settings::ControllerType::ProController)));
+
+ if (!player_prefix.empty() || !Settings::IsConfiguringGlobal()) {
+ WriteSetting(std::string(player_prefix).append("connected"), player.connected,
+ std::make_optional(player_index == 0));
+ WriteSetting(std::string(player_prefix).append("vibration_enabled"),
+ player.vibration_enabled, std::make_optional(true));
+ WriteSetting(std::string(player_prefix).append("vibration_strength"),
+ player.vibration_strength, std::make_optional(100));
+ WriteSetting(std::string(player_prefix).append("body_color_left"), player.body_color_left,
+ std::make_optional(Settings::JOYCON_BODY_NEON_BLUE));
+ WriteSetting(std::string(player_prefix).append("body_color_right"), player.body_color_right,
+ std::make_optional(Settings::JOYCON_BODY_NEON_RED));
+ WriteSetting(std::string(player_prefix).append("button_color_left"),
+ player.button_color_left,
+ std::make_optional(Settings::JOYCON_BUTTONS_NEON_BLUE));
+ WriteSetting(std::string(player_prefix).append("button_color_right"),
+ player.button_color_right,
+ std::make_optional(Settings::JOYCON_BUTTONS_NEON_RED));
+ }
+}
+
+void Config::SaveTouchscreenValues() {
+ const auto& touchscreen = Settings::values.touchscreen;
+
+ WriteSetting(std::string("touchscreen_enabled"), touchscreen.enabled, std::make_optional(true));
+
+ WriteSetting(std::string("touchscreen_angle"), touchscreen.rotation_angle,
+ std::make_optional(static_cast<u32>(0)));
+ WriteSetting(std::string("touchscreen_diameter_x"), touchscreen.diameter_x,
+ std::make_optional(static_cast<u32>(15)));
+ WriteSetting(std::string("touchscreen_diameter_y"), touchscreen.diameter_y,
+ std::make_optional(static_cast<u32>(15)));
+}
+
+void Config::SaveMotionTouchValues() {
+ BeginArray(std::string("touch_from_button_maps"));
+ for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
+ SetArrayIndex(static_cast<int>(p));
+ WriteSetting(std::string("name"), Settings::values.touch_from_button_maps[p].name,
+ std::make_optional(std::string("default")));
+
+ BeginArray(std::string("entries"));
+ for (std::size_t q = 0; q < Settings::values.touch_from_button_maps[p].buttons.size();
+ ++q) {
+ SetArrayIndex(static_cast<int>(q));
+ WriteSetting(std::string("bind"),
+ Settings::values.touch_from_button_maps[p].buttons[q]);
+ }
+ EndArray(); // entries
+ }
+ EndArray(); // touch_from_button_maps
+}
+
+void Config::SaveValues() {
+ if (global) {
+ SaveDataStorageValues();
+ SaveDebuggingValues();
+ SaveDisabledAddOnValues();
+ SaveNetworkValues();
+ SaveWebServiceValues();
+ SaveMiscellaneousValues();
+ }
+ SaveControlValues();
+ SaveCoreValues();
+ SaveCpuValues();
+ SaveRendererValues();
+ SaveAudioValues();
+ SaveSystemValues();
+
+ WriteToIni();
+}
+
+void Config::SaveAudioValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Audio));
+
+ WriteCategory(Settings::Category::Audio);
+ WriteCategory(Settings::Category::UiAudio);
+
+ EndGroup();
+}
+
+void Config::SaveControlValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ WriteCategory(Settings::Category::Controls);
+
+ Settings::values.players.SetGlobal(!IsCustomConfig());
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
+ SavePlayerValues(p);
+ }
+ if (IsCustomConfig()) {
+ EndGroup();
+ return;
+ }
+ SaveTouchscreenValues();
+ SaveMotionTouchValues();
+
+ EndGroup();
+}
+
+void Config::SaveCoreValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Core));
+
+ WriteCategory(Settings::Category::Core);
+
+ EndGroup();
+}
+
+void Config::SaveDataStorageValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
+
+ WriteSetting(std::string("nand_directory"), FS::GetYuzuPathString(FS::YuzuPath::NANDDir),
+ std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
+ WriteSetting(std::string("sdmc_directory"), FS::GetYuzuPathString(FS::YuzuPath::SDMCDir),
+ std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
+ WriteSetting(std::string("load_directory"), FS::GetYuzuPathString(FS::YuzuPath::LoadDir),
+ std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
+ WriteSetting(std::string("dump_directory"), FS::GetYuzuPathString(FS::YuzuPath::DumpDir),
+ std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
+ WriteSetting(std::string("tas_directory"), FS::GetYuzuPathString(FS::YuzuPath::TASDir),
+ std::make_optional(FS::GetYuzuPathString(FS::YuzuPath::TASDir)));
+
+ WriteCategory(Settings::Category::DataStorage);
+
+ EndGroup();
+}
+
+void Config::SaveDebuggingValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Debugging));
+
+ // Intentionally not using the QT default setting as this is intended to be changed in the ini
+ WriteSetting(std::string("record_frame_times"), Settings::values.record_frame_times);
+
+ WriteCategory(Settings::Category::Debugging);
+ WriteCategory(Settings::Category::DebuggingGraphics);
+
+ EndGroup();
+}
+
+void Config::SaveNetworkValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Services));
+
+ WriteCategory(Settings::Category::Network);
+
+ EndGroup();
+}
+
+void Config::SaveDisabledAddOnValues() {
+ // Custom config section
+ BeginGroup(std::string("DisabledAddOns"));
+
+ int i = 0;
+ BeginArray(std::string(""));
+ for (const auto& elem : Settings::values.disabled_addons) {
+ SetArrayIndex(i);
+ WriteSetting(std::string("title_id"), elem.first, std::make_optional(static_cast<u64>(0)));
+ BeginArray(std::string("disabled"));
+ for (std::size_t j = 0; j < elem.second.size(); ++j) {
+ SetArrayIndex(static_cast<int>(j));
+ WriteSetting(std::string("d"), elem.second[j], std::make_optional(std::string("")));
+ }
+ EndArray(); // disabled
+ ++i;
+ }
+ EndArray(); // Base disabled addons array - Has no base key
+
+ EndGroup();
+}
+
+void Config::SaveMiscellaneousValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Miscellaneous));
+
+ WriteCategory(Settings::Category::Miscellaneous);
+
+ EndGroup();
+}
+
+void Config::SaveCpuValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Cpu));
+
+ WriteCategory(Settings::Category::Cpu);
+ WriteCategory(Settings::Category::CpuDebug);
+ WriteCategory(Settings::Category::CpuUnsafe);
+
+ EndGroup();
+}
+
+void Config::SaveRendererValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Renderer));
+
+ WriteCategory(Settings::Category::Renderer);
+ WriteCategory(Settings::Category::RendererAdvanced);
+ WriteCategory(Settings::Category::RendererDebug);
+
+ EndGroup();
+}
+
+void Config::SaveScreenshotValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Screenshots));
+
+ WriteSetting(std::string("screenshot_path"),
+ FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir));
+ WriteCategory(Settings::Category::Screenshots);
+
+ EndGroup();
+}
+
+void Config::SaveSystemValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::System));
+
+ WriteCategory(Settings::Category::System);
+ WriteCategory(Settings::Category::SystemAudio);
+
+ EndGroup();
+}
+
+void Config::SaveWebServiceValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::WebService));
+
+ WriteCategory(Settings::Category::WebService);
+
+ EndGroup();
+}
+
+bool Config::ReadBooleanSetting(const std::string& key, const std::optional<bool> default_value) {
+ std::string full_key = GetFullKey(key, false);
+ if (!default_value.has_value()) {
+ return config->GetBoolValue(GetSection().c_str(), full_key.c_str(), false);
+ }
+
+ if (config->GetBoolValue(GetSection().c_str(),
+ std::string(full_key).append("\\default").c_str(), false)) {
+ return static_cast<bool>(default_value.value());
+ } else {
+ return config->GetBoolValue(GetSection().c_str(), full_key.c_str(),
+ static_cast<bool>(default_value.value()));
+ }
+}
+
+s64 Config::ReadIntegerSetting(const std::string& key, const std::optional<s64> default_value) {
+ std::string full_key = GetFullKey(key, false);
+ if (!default_value.has_value()) {
+ try {
+ return std::stoll(
+ std::string(config->GetValue(GetSection().c_str(), full_key.c_str(), "0")));
+ } catch (...) {
+ return 0;
+ }
+ }
+
+ s64 result = 0;
+ if (config->GetBoolValue(GetSection().c_str(),
+ std::string(full_key).append("\\default").c_str(), true)) {
+ result = default_value.value();
+ } else {
+ try {
+ result = std::stoll(std::string(config->GetValue(
+ GetSection().c_str(), full_key.c_str(), ToString(default_value.value()).c_str())));
+ } catch (...) {
+ result = default_value.value();
+ }
+ }
+ return result;
+}
+
+u64 Config::ReadUnsignedIntegerSetting(const std::string& key,
+ const std::optional<u64> default_value) {
+ std::string full_key = GetFullKey(key, false);
+ if (!default_value.has_value()) {
+ try {
+ return std::stoull(
+ std::string(config->GetValue(GetSection().c_str(), full_key.c_str(), "0")));
+ } catch (...) {
+ return 0;
+ }
+ }
+
+ u64 result = 0;
+ if (config->GetBoolValue(GetSection().c_str(),
+ std::string(full_key).append("\\default").c_str(), true)) {
+ result = default_value.value();
+ } else {
+ try {
+ result = std::stoull(std::string(config->GetValue(
+ GetSection().c_str(), full_key.c_str(), ToString(default_value.value()).c_str())));
+ } catch (...) {
+ result = default_value.value();
+ }
+ }
+ return result;
+}
+
+double Config::ReadDoubleSetting(const std::string& key,
+ const std::optional<double> default_value) {
+ std::string full_key = GetFullKey(key, false);
+ if (!default_value.has_value()) {
+ return config->GetDoubleValue(GetSection().c_str(), full_key.c_str(), 0);
+ }
+
+ double result;
+ if (config->GetBoolValue(GetSection().c_str(),
+ std::string(full_key).append("\\default").c_str(), true)) {
+ result = default_value.value();
+ } else {
+ result =
+ config->GetDoubleValue(GetSection().c_str(), full_key.c_str(), default_value.value());
+ }
+ return result;
+}
+
+std::string Config::ReadStringSetting(const std::string& key,
+ const std::optional<std::string> default_value) {
+ std::string result;
+ std::string full_key = GetFullKey(key, false);
+ if (!default_value.has_value()) {
+ result = config->GetValue(GetSection().c_str(), full_key.c_str(), "");
+ boost::replace_all(result, "\"", "");
+ return result;
+ }
+
+ if (config->GetBoolValue(GetSection().c_str(),
+ std::string(full_key).append("\\default").c_str(), true)) {
+ result = default_value.value();
+ } else {
+ result =
+ config->GetValue(GetSection().c_str(), full_key.c_str(), default_value.value().c_str());
+ }
+ boost::replace_all(result, "\"", "");
+ boost::replace_all(result, "//", "/");
+ return result;
+}
+
+bool Config::Exists(const std::string& section, const std::string& key) const {
+ const std::string value = config->GetValue(section.c_str(), key.c_str(), "");
+ return !value.empty();
+}
+
+template <typename Type>
+void Config::WriteSetting(const std::string& key, const Type& value,
+ const std::optional<Type>& default_value,
+ const std::optional<bool>& use_global) {
+ std::string full_key = GetFullKey(key, false);
+
+ std::string saved_value;
+ std::string string_default;
+ if constexpr (std::is_same_v<Type, std::string>) {
+ saved_value.append(AdjustOutputString(value));
+ if (default_value.has_value()) {
+ string_default.append(AdjustOutputString(default_value.value()));
+ }
+ } else {
+ saved_value.append(AdjustOutputString(ToString(value)));
+ if (default_value.has_value()) {
+ string_default.append(ToString(default_value.value()));
+ }
+ }
+
+ if (default_value.has_value() && use_global.has_value()) {
+ if (!global) {
+ WriteSettingInternal(std::string(full_key).append("\\global"),
+ ToString(use_global.value()));
+ }
+ if (global || use_global.value() == false) {
+ WriteSettingInternal(std::string(full_key).append("\\default"),
+ ToString(string_default == saved_value));
+ WriteSettingInternal(full_key, saved_value);
+ }
+ } else if (default_value.has_value() && !use_global.has_value()) {
+ WriteSettingInternal(std::string(full_key).append("\\default"),
+ ToString(string_default == saved_value));
+ WriteSettingInternal(full_key, saved_value);
+ } else {
+ WriteSettingInternal(full_key, saved_value);
+ }
+}
+
+void Config::WriteSettingInternal(const std::string& key, const std::string& value) {
+ config->SetValue(GetSection().c_str(), key.c_str(), value.c_str());
+}
+
+void Config::Reload() {
+ ReadValues();
+ // To apply default value changes
+ SaveValues();
+}
+
+void Config::Save() {
+ SaveValues();
+}
+
+void Config::ClearControlPlayerValues() const {
+ // If key is an empty string, all keys in the current group() are removed.
+ const char* section = Settings::TranslateCategory(Settings::Category::Controls);
+ CSimpleIniA::TNamesDepend keys;
+ config->GetAllKeys(section, keys);
+ for (const auto& key : keys) {
+ if (std::string(config->GetValue(section, key.pItem)).empty()) {
+ config->Delete(section, key.pItem);
+ }
+ }
+}
+
+const std::string& Config::GetConfigFilePath() const {
+ return config_loc;
+}
+
+void Config::ReadCategory(const Settings::Category category) {
+ const auto& settings = FindRelevantList(category);
+ std::ranges::for_each(settings, [&](const auto& setting) { ReadSettingGeneric(setting); });
+}
+
+void Config::WriteCategory(const Settings::Category category) {
+ const auto& settings = FindRelevantList(category);
+ std::ranges::for_each(settings, [&](const auto& setting) { WriteSettingGeneric(setting); });
+}
+
+void Config::ReadSettingGeneric(Settings::BasicSetting* const setting) {
+ if (!setting->Save() || (!setting->Switchable() && !global)) {
+ return;
+ }
+
+ const std::string key = AdjustKey(setting->GetLabel());
+ const std::string default_value(setting->DefaultToString());
+
+ bool use_global = true;
+ if (setting->Switchable() && !global) {
+ use_global =
+ ReadBooleanSetting(std::string(key).append("\\use_global"), std::make_optional(true));
+ setting->SetGlobal(use_global);
+ }
+
+ if (global || !use_global) {
+ const bool is_default =
+ ReadBooleanSetting(std::string(key).append("\\default"), std::make_optional(true));
+ if (!is_default) {
+ const std::string setting_string = ReadStringSetting(key, default_value);
+ setting->LoadString(setting_string);
+ } else {
+ // Empty string resets the Setting to default
+ setting->LoadString("");
+ }
+ }
+}
+
+void Config::WriteSettingGeneric(const Settings::BasicSetting* const setting) {
+ if (!setting->Save()) {
+ return;
+ }
+
+ std::string key = AdjustKey(setting->GetLabel());
+ if (setting->Switchable()) {
+ if (!global) {
+ WriteSetting(std::string(key).append("\\use_global"), setting->UsingGlobal());
+ }
+ if (global || !setting->UsingGlobal()) {
+ WriteSetting(std::string(key).append("\\default"),
+ setting->ToString() == setting->DefaultToString());
+ WriteSetting(key, setting->ToString());
+ }
+ } else if (global) {
+ WriteSetting(std::string(key).append("\\default"),
+ setting->ToString() == setting->DefaultToString());
+ WriteSetting(key, setting->ToString());
+ }
+}
+
+void Config::BeginGroup(const std::string& group) {
+ // You can't begin a group while reading/writing from a config array
+ ASSERT(array_stack.empty());
+
+ key_stack.push_back(AdjustKey(group));
+}
+
+void Config::EndGroup() {
+ // You can't end a group if you haven't started one yet
+ ASSERT(!key_stack.empty());
+
+ // You can't end a group when reading/writing from a config array
+ ASSERT(array_stack.empty());
+
+ key_stack.pop_back();
+}
+
+std::string Config::GetSection() {
+ if (key_stack.empty()) {
+ return std::string{""};
+ }
+
+ return key_stack.front();
+}
+
+std::string Config::GetGroup() const {
+ if (key_stack.size() <= 1) {
+ return std::string{""};
+ }
+
+ std::string key;
+ for (size_t i = 1; i < key_stack.size(); ++i) {
+ key.append(key_stack[i]).append("\\");
+ }
+ return key;
+}
+
+std::string Config::AdjustKey(const std::string& key) {
+ std::string adjusted_key(key);
+ boost::replace_all(adjusted_key, "/", "\\");
+ boost::replace_all(adjusted_key, " ", "%20");
+ return adjusted_key;
+}
+
+std::string Config::AdjustOutputString(const std::string& string) {
+ std::string adjusted_string(string);
+ boost::replace_all(adjusted_string, "\\", "/");
+
+ // Windows requires that two forward slashes are used at the start of a path for unmapped
+ // network drives so we have to watch for that here
+ if (string.substr(0, 2) == "//") {
+ boost::replace_all(adjusted_string, "//", "/");
+ adjusted_string.insert(0, "/");
+ } else {
+ boost::replace_all(adjusted_string, "//", "/");
+ }
+
+ // Needed for backwards compatibility with QSettings deserialization
+ for (const auto& special_character : special_characters) {
+ if (adjusted_string.find(special_character) != std::string::npos) {
+ adjusted_string.insert(0, "\"");
+ adjusted_string.append("\"");
+ break;
+ }
+ }
+ return adjusted_string;
+}
+
+std::string Config::GetFullKey(const std::string& key, bool skipArrayIndex) {
+ if (array_stack.empty()) {
+ return std::string(GetGroup()).append(AdjustKey(key));
+ }
+
+ std::string array_key;
+ for (size_t i = 0; i < array_stack.size(); ++i) {
+ if (!array_stack[i].name.empty()) {
+ array_key.append(array_stack[i].name).append("\\");
+ }
+
+ if (!skipArrayIndex || (array_stack.size() - 1 != i && array_stack.size() > 1)) {
+ array_key.append(ToString(array_stack[i].index)).append("\\");
+ }
+ }
+ std::string final_key = std::string(GetGroup()).append(array_key).append(AdjustKey(key));
+ return final_key;
+}
+
+int Config::BeginArray(const std::string& array) {
+ array_stack.push_back(ConfigArray{AdjustKey(array), 0, 0});
+ const int size = config->GetLongValue(GetSection().c_str(),
+ GetFullKey(std::string("size"), true).c_str(), 0);
+ array_stack.back().size = size;
+ return size;
+}
+
+void Config::EndArray() {
+ // You can't end a config array before starting one
+ ASSERT(!array_stack.empty());
+
+ // Set the array size to 0 if the array is ended without changing the index
+ int size = 0;
+ if (array_stack.back().index != 0) {
+ size = array_stack.back().size;
+ }
+
+ // Write out the size to config
+ if (key_stack.size() == 1 && array_stack.back().name.empty()) {
+ // Edge-case where the first array created doesn't have a name
+ config->SetValue(GetSection().c_str(), std::string("size").c_str(), ToString(size).c_str());
+ } else {
+ const auto key = GetFullKey(std::string("size"), true);
+ config->SetValue(GetSection().c_str(), key.c_str(), ToString(size).c_str());
+ }
+
+ array_stack.pop_back();
+}
+
+void Config::SetArrayIndex(const int index) {
+ // You can't set the array index if you haven't started one yet
+ ASSERT(!array_stack.empty());
+
+ const int array_index = index + 1;
+
+ // You can't exceed the known max size of the array by more than 1
+ ASSERT(array_stack.front().size + 1 >= array_index);
+
+ // Change the config array size to the current index since you may want
+ // to reduce the number of elements that you read back from the config
+ // in the future.
+ array_stack.back().size = array_index;
+ array_stack.back().index = array_index;
+}
diff --git a/src/frontend_common/config.h b/src/frontend_common/config.h
new file mode 100644
index 000000000..b3812af17
--- /dev/null
+++ b/src/frontend_common/config.h
@@ -0,0 +1,211 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include "common/settings.h"
+
+#define SI_NO_CONVERSION
+#include <SimpleIni.h>
+#include <boost/algorithm/string/replace.hpp>
+
+// Workaround for conflicting definition in libloaderapi.h caused by SimpleIni
+#undef LoadString
+#undef CreateFile
+#undef DeleteFile
+#undef CopyFile
+#undef CreateDirectory
+#undef MoveFile
+
+namespace Core {
+class System;
+}
+
+class Config {
+public:
+ enum class ConfigType {
+ GlobalConfig,
+ PerGameConfig,
+ InputProfile,
+ };
+
+ virtual ~Config() = default;
+
+ void ClearControlPlayerValues() const;
+
+ [[nodiscard]] const std::string& GetConfigFilePath() const;
+
+ [[nodiscard]] bool Exists(const std::string& section, const std::string& key) const;
+
+protected:
+ explicit Config(ConfigType config_type = ConfigType::GlobalConfig);
+
+ void Initialize(const std::string& config_name = "config");
+ void Initialize(std::optional<std::string> config_path);
+
+ void WriteToIni() const;
+
+ void SetUpIni();
+ [[nodiscard]] bool IsCustomConfig() const;
+
+ void Reload();
+ void Save();
+
+ /**
+ * Derived config classes must implement this so they can reload all platform-specific
+ * values and global ones.
+ */
+ virtual void ReloadAllValues() = 0;
+
+ /**
+ * Derived config classes must implement this so they can save all platform-specific
+ * and global values.
+ */
+ virtual void SaveAllValues() = 0;
+
+ void ReadValues();
+ void ReadPlayerValues(std::size_t player_index);
+
+ void ReadTouchscreenValues();
+ void ReadMotionTouchValues();
+
+ // Read functions bases off the respective config section names.
+ void ReadAudioValues();
+ void ReadControlValues();
+ void ReadCoreValues();
+ void ReadDataStorageValues();
+ void ReadDebuggingValues();
+ void ReadServiceValues();
+ void ReadDisabledAddOnValues();
+ void ReadMiscellaneousValues();
+ void ReadCpuValues();
+ void ReadRendererValues();
+ void ReadScreenshotValues();
+ void ReadSystemValues();
+ void ReadWebServiceValues();
+ void ReadNetworkValues();
+
+ // Read platform specific sections
+ virtual void ReadHidbusValues() = 0;
+ virtual void ReadDebugControlValues() = 0;
+ virtual void ReadPathValues() = 0;
+ virtual void ReadShortcutValues() = 0;
+ virtual void ReadUIValues() = 0;
+ virtual void ReadUIGamelistValues() = 0;
+ virtual void ReadUILayoutValues() = 0;
+ virtual void ReadMultiplayerValues() = 0;
+
+ void SaveValues();
+ void SavePlayerValues(std::size_t player_index);
+ void SaveTouchscreenValues();
+ void SaveMotionTouchValues();
+
+ // Save functions based off the respective config section names.
+ void SaveAudioValues();
+ void SaveControlValues();
+ void SaveCoreValues();
+ void SaveDataStorageValues();
+ void SaveDebuggingValues();
+ void SaveNetworkValues();
+ void SaveDisabledAddOnValues();
+ void SaveMiscellaneousValues();
+ void SaveCpuValues();
+ void SaveRendererValues();
+ void SaveScreenshotValues();
+ void SaveSystemValues();
+ void SaveWebServiceValues();
+
+ // Save platform specific sections
+ virtual void SaveHidbusValues() = 0;
+ virtual void SaveDebugControlValues() = 0;
+ virtual void SavePathValues() = 0;
+ virtual void SaveShortcutValues() = 0;
+ virtual void SaveUIValues() = 0;
+ virtual void SaveUIGamelistValues() = 0;
+ virtual void SaveUILayoutValues() = 0;
+ virtual void SaveMultiplayerValues() = 0;
+
+ virtual std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) = 0;
+
+ /**
+ * Reads a setting from the qt_config.
+ *
+ * @param key The setting's identifier
+ * @param default_value The value to use when the setting is not already present in the config
+ */
+ bool ReadBooleanSetting(const std::string& key,
+ std::optional<bool> default_value = std::nullopt);
+ s64 ReadIntegerSetting(const std::string& key, std::optional<s64> default_value = std::nullopt);
+ u64 ReadUnsignedIntegerSetting(const std::string& key,
+ std::optional<u64> default_value = std::nullopt);
+ double ReadDoubleSetting(const std::string& key,
+ std::optional<double> default_value = std::nullopt);
+ std::string ReadStringSetting(const std::string& key,
+ std::optional<std::string> default_value = std::nullopt);
+
+ /**
+ * Writes a setting to the qt_config.
+ *
+ * @param key The setting's idetentifier
+ * @param value Value of the setting
+ * @param default_value Default of the setting if not present in config
+ * @param use_global Specifies if the custom or global config should be in use, for custom
+ * configs
+ */
+ template <typename Type = int>
+ void WriteSetting(const std::string& key, const Type& value,
+ const std::optional<Type>& default_value = std::nullopt,
+ const std::optional<bool>& use_global = std::nullopt);
+ void WriteSettingInternal(const std::string& key, const std::string& value);
+
+ void ReadCategory(Settings::Category category);
+ void WriteCategory(Settings::Category category);
+ void ReadSettingGeneric(Settings::BasicSetting* setting);
+ void WriteSettingGeneric(const Settings::BasicSetting* setting);
+
+ template <typename T>
+ [[nodiscard]] std::string ToString(const T& value_) {
+ if constexpr (std::is_same_v<T, std::string>) {
+ return value_;
+ } else if constexpr (std::is_same_v<T, std::optional<u32>>) {
+ return value_.has_value() ? std::to_string(*value_) : "none";
+ } else if constexpr (std::is_same_v<T, bool>) {
+ return value_ ? "true" : "false";
+ } else if constexpr (std::is_same_v<T, u64>) {
+ return std::to_string(static_cast<u64>(value_));
+ } else {
+ return std::to_string(static_cast<s64>(value_));
+ }
+ }
+
+ void BeginGroup(const std::string& group);
+ void EndGroup();
+ std::string GetSection();
+ [[nodiscard]] std::string GetGroup() const;
+ static std::string AdjustKey(const std::string& key);
+ static std::string AdjustOutputString(const std::string& string);
+ std::string GetFullKey(const std::string& key, bool skipArrayIndex);
+ int BeginArray(const std::string& array);
+ void EndArray();
+ void SetArrayIndex(int index);
+
+ const ConfigType type;
+ std::unique_ptr<CSimpleIniA> config;
+ std::string config_loc;
+ const bool global;
+
+private:
+ inline static std::array<char, 19> special_characters = {'!', '#', '$', '%', '^', '&', '*',
+ '|', ';', '\'', '\"', ',', '<', '.',
+ '>', '?', '`', '~', '='};
+
+ struct ConfigArray {
+ std::string name;
+ int size;
+ int index;
+ };
+ std::vector<ConfigArray> array_stack;
+ std::vector<std::string> key_stack;
+};
diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp
index 3ad34884d..1ff296af5 100644
--- a/src/input_common/drivers/gc_adapter.cpp
+++ b/src/input_common/drivers/gc_adapter.cpp
@@ -415,7 +415,7 @@ ButtonMapping GCAdapter::GetButtonMappingForDevice(const Common::ParamPackage& p
// This list is missing ZL/ZR since those are not considered buttons.
// We will add those afterwards
// This list also excludes any button that can't be really mapped
- static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 12>
+ static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 14>
switch_to_gcadapter_button = {
std::pair{Settings::NativeButton::A, PadButton::ButtonA},
{Settings::NativeButton::B, PadButton::ButtonB},
@@ -426,8 +426,10 @@ ButtonMapping GCAdapter::GetButtonMappingForDevice(const Common::ParamPackage& p
{Settings::NativeButton::DUp, PadButton::ButtonUp},
{Settings::NativeButton::DRight, PadButton::ButtonRight},
{Settings::NativeButton::DDown, PadButton::ButtonDown},
- {Settings::NativeButton::SL, PadButton::TriggerL},
- {Settings::NativeButton::SR, PadButton::TriggerR},
+ {Settings::NativeButton::SLLeft, PadButton::TriggerL},
+ {Settings::NativeButton::SRLeft, PadButton::TriggerR},
+ {Settings::NativeButton::SLRight, PadButton::TriggerL},
+ {Settings::NativeButton::SRRight, PadButton::TriggerR},
{Settings::NativeButton::R, PadButton::TriggerZ},
};
if (!params.Has("port")) {
diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp
index 0aca5a3a3..72d2951f3 100644
--- a/src/input_common/drivers/joycon.cpp
+++ b/src/input_common/drivers/joycon.cpp
@@ -680,8 +680,8 @@ ButtonMapping Joycons::GetButtonMappingForDevice(const Common::ParamPackage& par
Common::ParamPackage sr_button_params = button_params;
sl_button_params.Set("button", static_cast<int>(Joycon::PadButton::LeftSL));
sr_button_params.Set("button", static_cast<int>(Joycon::PadButton::LeftSR));
- mapping.insert_or_assign(Settings::NativeButton::SL, std::move(sl_button_params));
- mapping.insert_or_assign(Settings::NativeButton::SR, std::move(sr_button_params));
+ mapping.insert_or_assign(Settings::NativeButton::SLLeft, std::move(sl_button_params));
+ mapping.insert_or_assign(Settings::NativeButton::SRLeft, std::move(sr_button_params));
}
// Map SL and SR buttons for right joycons
@@ -693,8 +693,8 @@ ButtonMapping Joycons::GetButtonMappingForDevice(const Common::ParamPackage& par
Common::ParamPackage sr_button_params = button_params;
sl_button_params.Set("button", static_cast<int>(Joycon::PadButton::RightSL));
sr_button_params.Set("button", static_cast<int>(Joycon::PadButton::RightSR));
- mapping.insert_or_assign(Settings::NativeButton::SL, std::move(sl_button_params));
- mapping.insert_or_assign(Settings::NativeButton::SR, std::move(sr_button_params));
+ mapping.insert_or_assign(Settings::NativeButton::SLRight, std::move(sl_button_params));
+ mapping.insert_or_assign(Settings::NativeButton::SRRight, std::move(sr_button_params));
}
return mapping;
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index 66e3ae9af..78f458afe 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -828,16 +828,18 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p
ButtonBindings SDLDriver::GetDefaultButtonBinding(
const std::shared_ptr<SDLJoystick>& joystick) const {
// Default SL/SR mapping for other controllers
- auto sl_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
- auto sr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
+ auto sll_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
+ auto srl_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
+ auto slr_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
+ auto srr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
if (joystick->IsJoyconLeft()) {
- sl_button = SDL_CONTROLLER_BUTTON_PADDLE2;
- sr_button = SDL_CONTROLLER_BUTTON_PADDLE4;
+ sll_button = SDL_CONTROLLER_BUTTON_PADDLE2;
+ srl_button = SDL_CONTROLLER_BUTTON_PADDLE4;
}
if (joystick->IsJoyconRight()) {
- sl_button = SDL_CONTROLLER_BUTTON_PADDLE3;
- sr_button = SDL_CONTROLLER_BUTTON_PADDLE1;
+ slr_button = SDL_CONTROLLER_BUTTON_PADDLE3;
+ srr_button = SDL_CONTROLLER_BUTTON_PADDLE1;
}
return {
@@ -855,8 +857,10 @@ ButtonBindings SDLDriver::GetDefaultButtonBinding(
{Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP},
{Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
{Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN},
- {Settings::NativeButton::SL, sl_button},
- {Settings::NativeButton::SR, sr_button},
+ {Settings::NativeButton::SLLeft, sll_button},
+ {Settings::NativeButton::SRLeft, srl_button},
+ {Settings::NativeButton::SLRight, slr_button},
+ {Settings::NativeButton::SRRight, srr_button},
{Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE},
{Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1},
};
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h
index fcba4e3c6..08e49a0da 100644
--- a/src/input_common/drivers/sdl_driver.h
+++ b/src/input_common/drivers/sdl_driver.h
@@ -24,7 +24,7 @@ namespace InputCommon {
class SDLJoystick;
using ButtonBindings =
- std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 18>;
+ std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 20>;
using ZButtonBindings =
std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerAxis>, 2>;
diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp
index 77db60e92..60821b31a 100644
--- a/src/input_common/drivers/udp_client.cpp
+++ b/src/input_common/drivers/udp_client.cpp
@@ -396,7 +396,7 @@ std::vector<Common::ParamPackage> UDPClient::GetInputDevices() const {
ButtonMapping UDPClient::GetButtonMappingForDevice(const Common::ParamPackage& params) {
// This list excludes any button that can't be really mapped
- static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 20>
+ static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 22>
switch_to_dsu_button = {
std::pair{Settings::NativeButton::A, PadButton::Circle},
{Settings::NativeButton::B, PadButton::Cross},
@@ -412,8 +412,10 @@ ButtonMapping UDPClient::GetButtonMappingForDevice(const Common::ParamPackage& p
{Settings::NativeButton::R, PadButton::R1},
{Settings::NativeButton::ZL, PadButton::L2},
{Settings::NativeButton::ZR, PadButton::R2},
- {Settings::NativeButton::SL, PadButton::L2},
- {Settings::NativeButton::SR, PadButton::R2},
+ {Settings::NativeButton::SLLeft, PadButton::L2},
+ {Settings::NativeButton::SRLeft, PadButton::R2},
+ {Settings::NativeButton::SLRight, PadButton::L2},
+ {Settings::NativeButton::SRRight, PadButton::R2},
{Settings::NativeButton::LStick, PadButton::L3},
{Settings::NativeButton::RStick, PadButton::R3},
{Settings::NativeButton::Home, PadButton::Home},
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 83b763447..19db17c6d 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -231,6 +231,7 @@ add_library(shader_recompiler STATIC
ir_opt/rescaling_pass.cpp
ir_opt/ssa_rewrite_pass.cpp
ir_opt/texture_pass.cpp
+ ir_opt/vendor_workaround_pass.cpp
ir_opt/verification_pass.cpp
object_pool.h
precompiled_headers.h
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
index d0e308124..64e7bad75 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
@@ -559,12 +559,12 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
const IR::Value& offset, const IR::Value& lod_clamp) {
const auto info{inst.Flags<IR::TextureInstInfo>()};
ScopedRegister dpdx, dpdy, coords;
- const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp};
+ const bool multi_component{info.num_derivatives > 1 || info.has_lod_clamp};
if (multi_component) {
// Allocate this early to avoid aliasing other registers
dpdx = ScopedRegister{ctx.reg_alloc};
dpdy = ScopedRegister{ctx.reg_alloc};
- if (info.num_derivates >= 3) {
+ if (info.num_derivatives >= 3) {
coords = ScopedRegister{ctx.reg_alloc};
}
}
@@ -584,7 +584,7 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
dpdx.reg, derivatives_vec, dpdx.reg, derivatives_vec, dpdy.reg, derivatives_vec,
dpdy.reg, derivatives_vec);
Register final_coord;
- if (info.num_derivates >= 3) {
+ if (info.num_derivatives >= 3) {
ctx.Add("MOV.F {}.z,{}.x;"
"MOV.F {}.z,{}.y;",
dpdx.reg, coord_vec, dpdy.reg, coord_vec);
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
index d9872ecc2..6e940bd5a 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
@@ -548,15 +548,15 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
if (sparse_inst) {
throw NotImplementedException("EmitImageGradient Sparse");
}
- if (!offset.IsEmpty() && info.num_derivates <= 2) {
+ if (!offset.IsEmpty() && info.num_derivatives <= 2) {
throw NotImplementedException("EmitImageGradient offset");
}
const auto texture{Texture(ctx, info, index)};
const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)};
- const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp};
+ const bool multi_component{info.num_derivatives > 1 || info.has_lod_clamp};
const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)};
if (multi_component) {
- if (info.num_derivates >= 3) {
+ if (info.num_derivatives >= 3) {
const auto offset_vec{ctx.var_alloc.Consume(offset)};
ctx.Add("{}=textureGrad({},{},vec3({}.xz, {}.x),vec3({}.yw, {}.y));", texel, texture,
coords, derivatives_vec, offset_vec, derivatives_vec, offset_vec);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index 34592a01f..0031fa5fb 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -407,7 +407,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
}
ctx.AddCapability(spv::Capability::DemoteToHelperInvocation);
}
- if (info.stores[IR::Attribute::ViewportIndex]) {
+ if (info.stores[IR::Attribute::ViewportIndex] && profile.support_multi_viewport) {
ctx.AddCapability(spv::Capability::MultiViewport);
}
if (info.stores[IR::Attribute::ViewportMask] && profile.support_viewport_mask) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index 1d77426e0..e5a78a914 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -84,6 +84,10 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
}
return std::nullopt;
case IR::Attribute::ViewportIndex:
+ if (!ctx.profile.support_multi_viewport) {
+ LOG_WARNING(Shader, "Ignoring viewport index store on non-supporting driver");
+ return std::nullopt;
+ }
if (ctx.profile.support_viewport_index_layer_non_geometry ||
ctx.stage == Shader::Stage::Geometry) {
return OutAttr{ctx.viewport_index, ctx.U32[1]};
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 8decdf399..22ceca19c 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -67,22 +67,22 @@ public:
}
}
- explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivates, u32 num_derivates,
- Id offset, Id lod_clamp) {
- if (!Sirit::ValidId(derivates)) {
- throw LogicError("Derivates must be present");
+ explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivatives,
+ u32 num_derivatives, Id offset, Id lod_clamp) {
+ if (!Sirit::ValidId(derivatives)) {
+ throw LogicError("Derivatives must be present");
}
boost::container::static_vector<Id, 3> deriv_x_accum;
boost::container::static_vector<Id, 3> deriv_y_accum;
- for (u32 i = 0; i < num_derivates; ++i) {
- deriv_x_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivates, i * 2));
- deriv_y_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivates, i * 2 + 1));
+ for (u32 i = 0; i < num_derivatives; ++i) {
+ deriv_x_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivatives, i * 2));
+ deriv_y_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivatives, i * 2 + 1));
}
- const Id derivates_X{ctx.OpCompositeConstruct(
- ctx.F32[num_derivates], std::span{deriv_x_accum.data(), deriv_x_accum.size()})};
- const Id derivates_Y{ctx.OpCompositeConstruct(
- ctx.F32[num_derivates], std::span{deriv_y_accum.data(), deriv_y_accum.size()})};
- Add(spv::ImageOperandsMask::Grad, derivates_X, derivates_Y);
+ const Id derivatives_X{ctx.OpCompositeConstruct(
+ ctx.F32[num_derivatives], std::span{deriv_x_accum.data(), deriv_x_accum.size()})};
+ const Id derivatives_Y{ctx.OpCompositeConstruct(
+ ctx.F32[num_derivatives], std::span{deriv_y_accum.data(), deriv_y_accum.size()})};
+ Add(spv::ImageOperandsMask::Grad, derivatives_X, derivatives_Y);
if (Sirit::ValidId(offset)) {
Add(spv::ImageOperandsMask::Offset, offset);
}
@@ -91,26 +91,26 @@ public:
}
}
- explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivates_1, Id derivates_2,
+ explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivatives_1, Id derivatives_2,
Id offset, Id lod_clamp) {
- if (!Sirit::ValidId(derivates_1) || !Sirit::ValidId(derivates_2)) {
- throw LogicError("Derivates must be present");
+ if (!Sirit::ValidId(derivatives_1) || !Sirit::ValidId(derivatives_2)) {
+ throw LogicError("Derivatives must be present");
}
boost::container::static_vector<Id, 3> deriv_1_accum{
- ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 0),
- ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 2),
- ctx.OpCompositeExtract(ctx.F32[1], derivates_2, 0),
+ ctx.OpCompositeExtract(ctx.F32[1], derivatives_1, 0),
+ ctx.OpCompositeExtract(ctx.F32[1], derivatives_1, 2),
+ ctx.OpCompositeExtract(ctx.F32[1], derivatives_2, 0),
};
boost::container::static_vector<Id, 3> deriv_2_accum{
- ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 1),
- ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 3),
- ctx.OpCompositeExtract(ctx.F32[1], derivates_2, 1),
+ ctx.OpCompositeExtract(ctx.F32[1], derivatives_1, 1),
+ ctx.OpCompositeExtract(ctx.F32[1], derivatives_1, 3),
+ ctx.OpCompositeExtract(ctx.F32[1], derivatives_2, 1),
};
- const Id derivates_id1{ctx.OpCompositeConstruct(
+ const Id derivatives_id1{ctx.OpCompositeConstruct(
ctx.F32[3], std::span{deriv_1_accum.data(), deriv_1_accum.size()})};
- const Id derivates_id2{ctx.OpCompositeConstruct(
+ const Id derivatives_id2{ctx.OpCompositeConstruct(
ctx.F32[3], std::span{deriv_2_accum.data(), deriv_2_accum.size()})};
- Add(spv::ImageOperandsMask::Grad, derivates_id1, derivates_id2);
+ Add(spv::ImageOperandsMask::Grad, derivatives_id1, derivatives_id2);
if (Sirit::ValidId(offset)) {
Add(spv::ImageOperandsMask::Offset, offset);
}
@@ -548,12 +548,12 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
}
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
- Id derivates, Id offset, Id lod_clamp) {
+ Id derivatives, Id offset, Id lod_clamp) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
const auto operands =
- info.num_derivates == 3
- ? ImageOperands(ctx, info.has_lod_clamp != 0, derivates, offset, {}, lod_clamp)
- : ImageOperands(ctx, info.has_lod_clamp != 0, derivates, info.num_derivates, offset,
+ info.num_derivatives == 3
+ ? ImageOperands(ctx, info.has_lod_clamp != 0, derivatives, offset, {}, lod_clamp)
+ : ImageOperands(ctx, info.has_lod_clamp != 0, derivatives, info.num_derivatives, offset,
lod_clamp);
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
index a440b557d..7d34575c8 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
@@ -543,7 +543,7 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
const IR::Value& skip_mips);
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords);
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
- Id derivates, Id offset, Id lod_clamp);
+ Id derivatives, Id offset, Id lod_clamp);
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords);
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id color);
Id EmitIsTextureScaled(EmitContext& ctx, const IR::Value& index);
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index b7caa4246..49171c470 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -1864,11 +1864,11 @@ Value IREmitter::ImageQueryLod(const Value& handle, const Value& coords, Texture
return Inst(op, Flags{info}, handle, coords);
}
-Value IREmitter::ImageGradient(const Value& handle, const Value& coords, const Value& derivates,
+Value IREmitter::ImageGradient(const Value& handle, const Value& coords, const Value& derivatives,
const Value& offset, const F32& lod_clamp, TextureInstInfo info) {
const Opcode op{handle.IsImmediate() ? Opcode::BoundImageGradient
: Opcode::BindlessImageGradient};
- return Inst(op, Flags{info}, handle, coords, derivates, offset, lod_clamp);
+ return Inst(op, Flags{info}, handle, coords, derivatives, offset, lod_clamp);
}
Value IREmitter::ImageRead(const Value& handle, const Value& coords, TextureInstInfo info) {
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index f3c81dbe1..6c30897f4 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -335,7 +335,7 @@ public:
[[nodiscard]] Value ImageFetch(const Value& handle, const Value& coords, const Value& offset,
const U32& lod, const U32& multisampling, TextureInstInfo info);
[[nodiscard]] Value ImageGradient(const Value& handle, const Value& coords,
- const Value& derivates, const Value& offset,
+ const Value& derivatives, const Value& offset,
const F32& lod_clamp, TextureInstInfo info);
[[nodiscard]] Value ImageRead(const Value& handle, const Value& coords, TextureInstInfo info);
void ImageWrite(const Value& handle, const Value& coords, const Value& color,
diff --git a/src/shader_recompiler/frontend/ir/modifiers.h b/src/shader_recompiler/frontend/ir/modifiers.h
index 1e9e8c8f5..c20c2401f 100644
--- a/src/shader_recompiler/frontend/ir/modifiers.h
+++ b/src/shader_recompiler/frontend/ir/modifiers.h
@@ -40,7 +40,7 @@ union TextureInstInfo {
BitField<21, 1, u32> has_lod_clamp;
BitField<22, 1, u32> relaxed_precision;
BitField<23, 2, u32> gather_component;
- BitField<25, 2, u32> num_derivates;
+ BitField<25, 2, u32> num_derivatives;
BitField<27, 3, ImageFormat> image_format;
BitField<30, 1, u32> ndv_is_active;
};
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gradient.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gradient.cpp
index dd34507bc..4ce3dd0cd 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gradient.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gradient.cpp
@@ -59,7 +59,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
BitField<51, 3, IR::Pred> sparse_pred;
BitField<0, 8, IR::Reg> dest_reg;
BitField<8, 8, IR::Reg> coord_reg;
- BitField<20, 8, IR::Reg> derivate_reg;
+ BitField<20, 8, IR::Reg> derivative_reg;
BitField<28, 3, TextureType> type;
BitField<31, 4, u64> mask;
BitField<36, 13, u64> cbuf_offset;
@@ -71,7 +71,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
}
IR::Value coords;
- u32 num_derivates{};
+ u32 num_derivatives{};
IR::Reg base_reg{txd.coord_reg};
IR::Reg last_reg;
IR::Value handle;
@@ -90,42 +90,42 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
switch (txd.type) {
case TextureType::_1D: {
coords = v.F(base_reg);
- num_derivates = 1;
+ num_derivatives = 1;
last_reg = base_reg + 1;
break;
}
case TextureType::ARRAY_1D: {
last_reg = base_reg + 1;
coords = v.ir.CompositeConstruct(v.F(base_reg), read_array());
- num_derivates = 1;
+ num_derivatives = 1;
break;
}
case TextureType::_2D: {
last_reg = base_reg + 2;
coords = v.ir.CompositeConstruct(v.F(base_reg), v.F(base_reg + 1));
- num_derivates = 2;
+ num_derivatives = 2;
break;
}
case TextureType::ARRAY_2D: {
last_reg = base_reg + 2;
coords = v.ir.CompositeConstruct(v.F(base_reg), v.F(base_reg + 1), read_array());
- num_derivates = 2;
+ num_derivatives = 2;
break;
}
default:
throw NotImplementedException("Invalid texture type");
}
- const IR::Reg derivate_reg{txd.derivate_reg};
- IR::Value derivates;
- switch (num_derivates) {
+ const IR::Reg derivative_reg{txd.derivative_reg};
+ IR::Value derivatives;
+ switch (num_derivatives) {
case 1: {
- derivates = v.ir.CompositeConstruct(v.F(derivate_reg), v.F(derivate_reg + 1));
+ derivatives = v.ir.CompositeConstruct(v.F(derivative_reg), v.F(derivative_reg + 1));
break;
}
case 2: {
- derivates = v.ir.CompositeConstruct(v.F(derivate_reg), v.F(derivate_reg + 1),
- v.F(derivate_reg + 2), v.F(derivate_reg + 3));
+ derivatives = v.ir.CompositeConstruct(v.F(derivative_reg), v.F(derivative_reg + 1),
+ v.F(derivative_reg + 2), v.F(derivative_reg + 3));
break;
}
default:
@@ -150,9 +150,10 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
IR::TextureInstInfo info{};
info.type.Assign(GetType(txd.type));
- info.num_derivates.Assign(num_derivates);
+ info.num_derivatives.Assign(num_derivatives);
info.has_lod_clamp.Assign(has_lod_clamp ? 1 : 0);
- const IR::Value sample{v.ir.ImageGradient(handle, coords, derivates, offset, lod_clamp, info)};
+ const IR::Value sample{
+ v.ir.ImageGradient(handle, coords, derivatives, offset, lod_clamp, info)};
IR::Reg dest_reg{txd.dest_reg};
for (size_t element = 0; element < 4; ++element) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index 47183cae1..321ea625b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -310,6 +310,7 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
}
Optimization::CollectShaderInfoPass(env, program);
Optimization::LayerPass(program, host_info);
+ Optimization::VendorWorkaroundPass(program);
CollectInterpolationInfo(env, program);
AddNVNStorageBuffers(program);
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index f46e55122..ec12c843a 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -428,7 +428,7 @@ void FoldFPAdd32(IR::Inst& inst) {
}
}
-bool FoldDerivateYFromCorrection(IR::Inst& inst) {
+bool FoldDerivativeYFromCorrection(IR::Inst& inst) {
const IR::Value lhs_value{inst.Arg(0)};
const IR::Value rhs_value{inst.Arg(1)};
IR::Inst* const lhs_op{lhs_value.InstRecursive()};
@@ -464,7 +464,7 @@ void FoldFPMul32(IR::Inst& inst) {
if (lhs_value.IsImmediate() || rhs_value.IsImmediate()) {
return;
}
- if (FoldDerivateYFromCorrection(inst)) {
+ if (FoldDerivativeYFromCorrection(inst)) {
return;
}
IR::Inst* const lhs_op{lhs_value.InstRecursive()};
@@ -699,7 +699,7 @@ void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) {
}
}
-bool FindGradient3DDerivates(std::array<IR::Value, 3>& results, IR::Value coord) {
+bool FindGradient3DDerivatives(std::array<IR::Value, 3>& results, IR::Value coord) {
if (coord.IsImmediate()) {
return false;
}
@@ -834,7 +834,7 @@ void FoldImageSampleImplicitLod(IR::Block& block, IR::Inst& inst) {
IR::Inst* const inst2 = coords.InstRecursive();
std::array<std::array<IR::Value, 3>, 3> results_matrix;
for (size_t i = 0; i < 3; i++) {
- if (!FindGradient3DDerivates(results_matrix[i], inst2->Arg(i).Resolve())) {
+ if (!FindGradient3DDerivatives(results_matrix[i], inst2->Arg(i).Resolve())) {
return;
}
}
@@ -852,7 +852,7 @@ void FoldImageSampleImplicitLod(IR::Block& block, IR::Inst& inst) {
IR::Value derivatives_1 = ir.CompositeConstruct(results_matrix[0][1], results_matrix[0][2],
results_matrix[1][1], results_matrix[1][2]);
IR::Value derivatives_2 = ir.CompositeConstruct(results_matrix[2][1], results_matrix[2][2]);
- info.num_derivates.Assign(3);
+ info.num_derivatives.Assign(3);
IR::Value new_gradient_instruction =
ir.ImageGradient(handle, new_coords, derivatives_1, derivatives_2, lod_clamp, info);
IR::Inst* const new_inst = new_gradient_instruction.InstRecursive();
diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h
index 7082fc5f2..1e637cb23 100644
--- a/src/shader_recompiler/ir_opt/passes.h
+++ b/src/shader_recompiler/ir_opt/passes.h
@@ -26,6 +26,7 @@ void SsaRewritePass(IR::Program& program);
void PositionPass(Environment& env, IR::Program& program);
void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo& host_info);
void LayerPass(IR::Program& program, const HostTranslateInfo& host_info);
+void VendorWorkaroundPass(IR::Program& program);
void VerificationPass(const IR::Program& program);
// Dual Vertex
diff --git a/src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp b/src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp
new file mode 100644
index 000000000..08c658cb8
--- /dev/null
+++ b/src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp
@@ -0,0 +1,79 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "shader_recompiler/frontend/ir/basic_block.h"
+#include "shader_recompiler/frontend/ir/ir_emitter.h"
+#include "shader_recompiler/frontend/ir/value.h"
+#include "shader_recompiler/ir_opt/passes.h"
+
+namespace Shader::Optimization {
+
+namespace {
+void AddingByteSwapsWorkaround(IR::Block& block, IR::Inst& inst) {
+ /*
+ * Workaround for an NVIDIA bug seen in Super Mario RPG
+ *
+ * We are looking for this pattern:
+ * %lhs_bfe = BitFieldUExtract %factor_a, #0, #16
+ * %lhs_mul = IMul32 %lhs_bfe, %factor_b // potentially optional?
+ * %lhs_shl = ShiftLeftLogical32 %lhs_mul, #16
+ * %rhs_bfe = BitFieldUExtract %factor_a, #16, #16
+ * %result = IAdd32 %lhs_shl, %rhs_bfe
+ *
+ * And replacing the IAdd32 with a BitwiseOr32
+ * %result = BitwiseOr32 %lhs_shl, %rhs_bfe
+ *
+ */
+ IR::Inst* const lhs_shl{inst.Arg(0).TryInstRecursive()};
+ IR::Inst* const rhs_bfe{inst.Arg(1).TryInstRecursive()};
+ if (!lhs_shl || !rhs_bfe) {
+ return;
+ }
+ if (lhs_shl->GetOpcode() != IR::Opcode::ShiftLeftLogical32 ||
+ lhs_shl->Arg(1) != IR::Value{16U}) {
+ return;
+ }
+ if (rhs_bfe->GetOpcode() != IR::Opcode::BitFieldUExtract || rhs_bfe->Arg(1) != IR::Value{16U} ||
+ rhs_bfe->Arg(2) != IR::Value{16U}) {
+ return;
+ }
+ IR::Inst* const lhs_mul{lhs_shl->Arg(0).TryInstRecursive()};
+ if (!lhs_mul) {
+ return;
+ }
+ const bool lhs_mul_optional{lhs_mul->GetOpcode() == IR::Opcode::BitFieldUExtract};
+ if (lhs_mul->GetOpcode() != IR::Opcode::IMul32 &&
+ lhs_mul->GetOpcode() != IR::Opcode::BitFieldUExtract) {
+ return;
+ }
+ IR::Inst* const lhs_bfe{lhs_mul_optional ? lhs_mul : lhs_mul->Arg(0).TryInstRecursive()};
+ if (!lhs_bfe) {
+ return;
+ }
+ if (lhs_bfe->GetOpcode() != IR::Opcode::BitFieldUExtract) {
+ return;
+ }
+ if (lhs_bfe->Arg(1) != IR::Value{0U} || lhs_bfe->Arg(2) != IR::Value{16U}) {
+ return;
+ }
+ IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
+ inst.ReplaceUsesWith(ir.BitwiseOr(IR::U32{inst.Arg(0)}, IR::U32{inst.Arg(1)}));
+}
+
+} // Anonymous namespace
+
+void VendorWorkaroundPass(IR::Program& program) {
+ for (IR::Block* const block : program.post_order_blocks) {
+ for (IR::Inst& inst : block->Instructions()) {
+ switch (inst.GetOpcode()) {
+ case IR::Opcode::IAdd32:
+ AddingByteSwapsWorkaround(*block, inst);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+} // namespace Shader::Optimization
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h
index e62ba8a20..66901a965 100644
--- a/src/shader_recompiler/profile.h
+++ b/src/shader_recompiler/profile.h
@@ -43,6 +43,7 @@ struct Profile {
bool support_gl_sparse_textures{};
bool support_gl_derivative_control{};
bool support_scaled_attributes{};
+ bool support_multi_viewport{};
bool warp_size_potentially_larger_than_guest{};
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index cf9266d54..c22c7631c 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -4,7 +4,7 @@
add_subdirectory(host_shaders)
if(LIBVA_FOUND)
- set_source_files_properties(host1x/codecs/codec.cpp
+ set_source_files_properties(host1x/ffmpeg/ffmpeg.cpp
PROPERTIES COMPILE_DEFINITIONS LIBVA_FOUND=1)
list(APPEND FFmpeg_LIBRARIES ${LIBVA_LIBRARIES})
endif()
@@ -15,6 +15,7 @@ add_library(video_core STATIC
buffer_cache/buffer_cache.cpp
buffer_cache/buffer_cache.h
buffer_cache/memory_tracker_base.h
+ buffer_cache/usage_tracker.h
buffer_cache/word_manager.h
cache_types.h
cdma_pusher.cpp
@@ -66,6 +67,8 @@ add_library(video_core STATIC
host1x/codecs/vp9.cpp
host1x/codecs/vp9.h
host1x/codecs/vp9_types.h
+ host1x/ffmpeg/ffmpeg.cpp
+ host1x/ffmpeg/ffmpeg.h
host1x/control.cpp
host1x/control.h
host1x/host1x.cpp
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 2648970b6..6d1fc3887 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -67,6 +67,7 @@ void BufferCache<P>::TickFrame() {
if (!channel_state) {
return;
}
+ runtime.TickFrame(slot_buffers);
// Calculate hits and shots and move hit bits to the right
const u32 hits = std::reduce(channel_state->uniform_cache_hits.begin(),
@@ -230,7 +231,10 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am
for (const IntervalType& add_interval : tmp_intervals) {
common_ranges.add(add_interval);
}
- runtime.CopyBuffer(dest_buffer, src_buffer, copies);
+ const auto& copy = copies[0];
+ src_buffer.MarkUsage(copy.src_offset, copy.size);
+ dest_buffer.MarkUsage(copy.dst_offset, copy.size);
+ runtime.CopyBuffer(dest_buffer, src_buffer, copies, true);
if (has_new_downloads) {
memory_tracker.MarkRegionAsGpuModified(*cpu_dest_address, amount);
}
@@ -258,9 +262,10 @@ bool BufferCache<P>::DMAClear(GPUVAddr dst_address, u64 amount, u32 value) {
common_ranges.subtract(subtract_interval);
const BufferId buffer = FindBuffer(*cpu_dst_address, static_cast<u32>(size));
- auto& dest_buffer = slot_buffers[buffer];
+ Buffer& dest_buffer = slot_buffers[buffer];
const u32 offset = dest_buffer.Offset(*cpu_dst_address);
runtime.ClearBuffer(dest_buffer, offset, size, value);
+ dest_buffer.MarkUsage(offset, size);
return true;
}
@@ -603,6 +608,7 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
VAddr orig_cpu_addr = static_cast<VAddr>(second_copy.src_offset);
const IntervalType base_interval{orig_cpu_addr, orig_cpu_addr + copy.size};
async_downloads += std::make_pair(base_interval, 1);
+ buffer.MarkUsage(copy.src_offset, copy.size);
runtime.CopyBuffer(download_staging.buffer, buffer, copies, false);
normalized_copies.push_back(second_copy);
}
@@ -621,8 +627,9 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
// Have in mind the staging buffer offset for the copy
copy.dst_offset += download_staging.offset;
const std::array copies{copy};
- runtime.CopyBuffer(download_staging.buffer, slot_buffers[buffer_id], copies,
- false);
+ Buffer& buffer = slot_buffers[buffer_id];
+ buffer.MarkUsage(copy.src_offset, copy.size);
+ runtime.CopyBuffer(download_staging.buffer, buffer, copies, false);
}
runtime.PostCopyBarrier();
runtime.Finish();
@@ -742,7 +749,7 @@ void BufferCache<P>::BindHostIndexBuffer() {
{BufferCopy{.src_offset = upload_staging.offset, .dst_offset = 0, .size = size}}};
std::memcpy(upload_staging.mapped_span.data(),
draw_state.inline_index_draw_indexes.data(), size);
- runtime.CopyBuffer(buffer, upload_staging.buffer, copies);
+ runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true);
} else {
buffer.ImmediateUpload(0, draw_state.inline_index_draw_indexes);
}
@@ -754,6 +761,7 @@ void BufferCache<P>::BindHostIndexBuffer() {
offset + draw_state.index_buffer.first * draw_state.index_buffer.FormatSizeInBytes();
runtime.BindIndexBuffer(buffer, new_offset, size);
} else {
+ buffer.MarkUsage(offset, size);
runtime.BindIndexBuffer(draw_state.topology, draw_state.index_buffer.format,
draw_state.index_buffer.first, draw_state.index_buffer.count,
buffer, offset, size);
@@ -790,6 +798,7 @@ void BufferCache<P>::BindHostVertexBuffers() {
const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
const u32 offset = buffer.Offset(binding.cpu_addr);
+ buffer.MarkUsage(offset, binding.size);
host_bindings.buffers.push_back(&buffer);
host_bindings.offsets.push_back(offset);
@@ -895,6 +904,7 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
}
+ buffer.MarkUsage(offset, size);
if constexpr (NEEDS_BIND_UNIFORM_INDEX) {
runtime.BindUniformBuffer(stage, binding_index, buffer, offset, size);
} else {
@@ -913,6 +923,7 @@ void BufferCache<P>::BindHostGraphicsStorageBuffers(size_t stage) {
SynchronizeBuffer(buffer, binding.cpu_addr, size);
const u32 offset = buffer.Offset(binding.cpu_addr);
+ buffer.MarkUsage(offset, size);
const bool is_written = ((channel_state->written_storage_buffers[stage] >> index) & 1) != 0;
if (is_written) {
@@ -943,6 +954,7 @@ void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) {
const u32 offset = buffer.Offset(binding.cpu_addr);
const PixelFormat format = binding.format;
+ buffer.MarkUsage(offset, size);
if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) {
if (((channel_state->image_texture_buffers[stage] >> index) & 1) != 0) {
runtime.BindImageBuffer(buffer, offset, size, format);
@@ -975,9 +987,10 @@ void BufferCache<P>::BindHostTransformFeedbackBuffers() {
MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, size);
const u32 offset = buffer.Offset(binding.cpu_addr);
+ buffer.MarkUsage(offset, size);
host_bindings.buffers.push_back(&buffer);
host_bindings.offsets.push_back(offset);
- host_bindings.sizes.push_back(binding.size);
+ host_bindings.sizes.push_back(size);
}
if (host_bindings.buffers.size() > 0) {
runtime.BindTransformFeedbackBuffers(host_bindings);
@@ -1001,6 +1014,7 @@ void BufferCache<P>::BindHostComputeUniformBuffers() {
SynchronizeBuffer(buffer, binding.cpu_addr, size);
const u32 offset = buffer.Offset(binding.cpu_addr);
+ buffer.MarkUsage(offset, size);
if constexpr (NEEDS_BIND_UNIFORM_INDEX) {
runtime.BindComputeUniformBuffer(binding_index, buffer, offset, size);
++binding_index;
@@ -1021,6 +1035,7 @@ void BufferCache<P>::BindHostComputeStorageBuffers() {
SynchronizeBuffer(buffer, binding.cpu_addr, size);
const u32 offset = buffer.Offset(binding.cpu_addr);
+ buffer.MarkUsage(offset, size);
const bool is_written =
((channel_state->written_compute_storage_buffers >> index) & 1) != 0;
@@ -1053,6 +1068,7 @@ void BufferCache<P>::BindHostComputeTextureBuffers() {
const u32 offset = buffer.Offset(binding.cpu_addr);
const PixelFormat format = binding.format;
+ buffer.MarkUsage(offset, size);
if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) {
if (((channel_state->image_compute_texture_buffers >> index) & 1) != 0) {
runtime.BindImageBuffer(buffer, offset, size, format);
@@ -1172,10 +1188,11 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) {
if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end)) {
size = static_cast<u32>(gpu_memory->MaxContinuousRange(gpu_addr_begin, size));
}
+ const BufferId buffer_id = FindBuffer(*cpu_addr, size);
channel_state->vertex_buffers[index] = Binding{
.cpu_addr = *cpu_addr,
.size = size,
- .buffer_id = FindBuffer(*cpu_addr, size),
+ .buffer_id = buffer_id,
};
}
@@ -1192,11 +1209,6 @@ void BufferCache<P>::UpdateDrawIndirect() {
.size = static_cast<u32>(size),
.buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)),
};
- VAddr cpu_addr_start = Common::AlignDown(*cpu_addr, 64);
- VAddr cpu_addr_end = Common::AlignUp(*cpu_addr + size, 64);
- IntervalType interval{cpu_addr_start, cpu_addr_end};
- ClearDownload(interval);
- common_ranges.subtract(interval);
};
if (current_draw_indirect->include_count) {
update(current_draw_indirect->count_start_address, sizeof(u32),
@@ -1406,7 +1418,8 @@ void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id,
.dst_offset = dst_base_offset,
.size = overlap.SizeBytes(),
});
- runtime.CopyBuffer(new_buffer, overlap, copies);
+ new_buffer.MarkUsage(copies[0].dst_offset, copies[0].size);
+ runtime.CopyBuffer(new_buffer, overlap, copies, true);
DeleteBuffer(overlap_id, true);
}
@@ -1419,7 +1432,9 @@ BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) {
const u32 size = static_cast<u32>(overlap.end - overlap.begin);
const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, overlap.begin, size);
auto& new_buffer = slot_buffers[new_buffer_id];
- runtime.ClearBuffer(new_buffer, 0, new_buffer.SizeBytes(), 0);
+ const size_t size_bytes = new_buffer.SizeBytes();
+ runtime.ClearBuffer(new_buffer, 0, size_bytes, 0);
+ new_buffer.MarkUsage(0, size_bytes);
for (const BufferId overlap_id : overlap.ids) {
JoinOverlap(new_buffer_id, overlap_id, !overlap.has_stream_leap);
}
@@ -1472,11 +1487,6 @@ void BufferCache<P>::TouchBuffer(Buffer& buffer, BufferId buffer_id) noexcept {
template <class P>
bool BufferCache<P>::SynchronizeBuffer(Buffer& buffer, VAddr cpu_addr, u32 size) {
- return SynchronizeBufferImpl(buffer, cpu_addr, size);
-}
-
-template <class P>
-bool BufferCache<P>::SynchronizeBufferImpl(Buffer& buffer, VAddr cpu_addr, u32 size) {
boost::container::small_vector<BufferCopy, 4> copies;
u64 total_size_bytes = 0;
u64 largest_copy = 0;
@@ -1499,51 +1509,6 @@ bool BufferCache<P>::SynchronizeBufferImpl(Buffer& buffer, VAddr cpu_addr, u32 s
}
template <class P>
-bool BufferCache<P>::SynchronizeBufferNoModified(Buffer& buffer, VAddr cpu_addr, u32 size) {
- boost::container::small_vector<BufferCopy, 4> copies;
- u64 total_size_bytes = 0;
- u64 largest_copy = 0;
- IntervalSet found_sets{};
- auto make_copies = [&] {
- for (auto& interval : found_sets) {
- const std::size_t sub_size = interval.upper() - interval.lower();
- const VAddr cpu_addr_ = interval.lower();
- copies.push_back(BufferCopy{
- .src_offset = total_size_bytes,
- .dst_offset = cpu_addr_ - buffer.CpuAddr(),
- .size = sub_size,
- });
- total_size_bytes += sub_size;
- largest_copy = std::max<u64>(largest_copy, sub_size);
- }
- const std::span<BufferCopy> copies_span(copies.data(), copies.size());
- UploadMemory(buffer, total_size_bytes, largest_copy, copies_span);
- };
- memory_tracker.ForEachUploadRange(cpu_addr, size, [&](u64 cpu_addr_out, u64 range_size) {
- const VAddr base_adr = cpu_addr_out;
- const VAddr end_adr = base_adr + range_size;
- const IntervalType add_interval{base_adr, end_adr};
- found_sets.add(add_interval);
- });
- if (found_sets.empty()) {
- return true;
- }
- const IntervalType search_interval{cpu_addr, cpu_addr + size};
- auto it = common_ranges.lower_bound(search_interval);
- auto it_end = common_ranges.upper_bound(search_interval);
- if (it == common_ranges.end()) {
- make_copies();
- return false;
- }
- while (it != it_end) {
- found_sets.subtract(*it);
- it++;
- }
- make_copies();
- return false;
-}
-
-template <class P>
void BufferCache<P>::UploadMemory(Buffer& buffer, u64 total_size_bytes, u64 largest_copy,
std::span<BufferCopy> copies) {
if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) {
@@ -1591,7 +1556,8 @@ void BufferCache<P>::MappedUploadMemory([[maybe_unused]] Buffer& buffer,
// Apply the staging offset
copy.src_offset += upload_staging.offset;
}
- runtime.CopyBuffer(buffer, upload_staging.buffer, copies);
+ const bool can_reorder = runtime.CanReorderUpload(buffer, copies);
+ runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true, can_reorder);
}
}
@@ -1633,7 +1599,8 @@ void BufferCache<P>::InlineMemoryImplementation(VAddr dest_address, size_t copy_
}};
u8* const src_pointer = upload_staging.mapped_span.data();
std::memcpy(src_pointer, inlined_buffer.data(), copy_size);
- runtime.CopyBuffer(buffer, upload_staging.buffer, copies);
+ const bool can_reorder = runtime.CanReorderUpload(buffer, copies);
+ runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true, can_reorder);
} else {
buffer.ImmediateUpload(buffer.Offset(dest_address), inlined_buffer.first(copy_size));
}
@@ -1686,8 +1653,9 @@ void BufferCache<P>::DownloadBufferMemory(Buffer& buffer, VAddr cpu_addr, u64 si
for (BufferCopy& copy : copies) {
// Modify copies to have the staging offset in mind
copy.dst_offset += download_staging.offset;
+ buffer.MarkUsage(copy.src_offset, copy.size);
}
- runtime.CopyBuffer(download_staging.buffer, buffer, copies_span);
+ runtime.CopyBuffer(download_staging.buffer, buffer, copies_span, true);
runtime.Finish();
for (const BufferCopy& copy : copies) {
const VAddr copy_cpu_addr = buffer.CpuAddr() + copy.src_offset;
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h
index eed267361..d6d696d8c 100644
--- a/src/video_core/buffer_cache/buffer_cache_base.h
+++ b/src/video_core/buffer_cache/buffer_cache_base.h
@@ -529,10 +529,6 @@ private:
bool SynchronizeBuffer(Buffer& buffer, VAddr cpu_addr, u32 size);
- bool SynchronizeBufferImpl(Buffer& buffer, VAddr cpu_addr, u32 size);
-
- bool SynchronizeBufferNoModified(Buffer& buffer, VAddr cpu_addr, u32 size);
-
void UploadMemory(Buffer& buffer, u64 total_size_bytes, u64 largest_copy,
std::span<BufferCopy> copies);
diff --git a/src/video_core/buffer_cache/usage_tracker.h b/src/video_core/buffer_cache/usage_tracker.h
new file mode 100644
index 000000000..ab05fe415
--- /dev/null
+++ b/src/video_core/buffer_cache/usage_tracker.h
@@ -0,0 +1,79 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "common/alignment.h"
+#include "common/common_types.h"
+
+namespace VideoCommon {
+
+class UsageTracker {
+ static constexpr size_t BYTES_PER_BIT_SHIFT = 6;
+ static constexpr size_t PAGE_SHIFT = 6 + BYTES_PER_BIT_SHIFT;
+ static constexpr size_t PAGE_BYTES = 1 << PAGE_SHIFT;
+
+public:
+ explicit UsageTracker(size_t size) {
+ const size_t num_pages = (size >> PAGE_SHIFT) + 1;
+ pages.resize(num_pages, 0ULL);
+ }
+
+ void Reset() noexcept {
+ std::ranges::fill(pages, 0ULL);
+ }
+
+ void Track(u64 offset, u64 size) noexcept {
+ const size_t page = offset >> PAGE_SHIFT;
+ const size_t page_end = (offset + size) >> PAGE_SHIFT;
+ TrackPage(page, offset, size);
+ if (page == page_end) {
+ return;
+ }
+ for (size_t i = page + 1; i < page_end; i++) {
+ pages[i] = ~u64{0};
+ }
+ const size_t offset_end = offset + size;
+ const size_t offset_end_page_aligned = Common::AlignDown(offset_end, PAGE_BYTES);
+ TrackPage(page_end, offset_end_page_aligned, offset_end - offset_end_page_aligned);
+ }
+
+ [[nodiscard]] bool IsUsed(u64 offset, u64 size) const noexcept {
+ const size_t page = offset >> PAGE_SHIFT;
+ const size_t page_end = (offset + size) >> PAGE_SHIFT;
+ if (IsPageUsed(page, offset, size)) {
+ return true;
+ }
+ for (size_t i = page + 1; i < page_end; i++) {
+ if (pages[i] != 0) {
+ return true;
+ }
+ }
+ const size_t offset_end = offset + size;
+ const size_t offset_end_page_aligned = Common::AlignDown(offset_end, PAGE_BYTES);
+ return IsPageUsed(page_end, offset_end_page_aligned, offset_end - offset_end_page_aligned);
+ }
+
+private:
+ void TrackPage(u64 page, u64 offset, u64 size) noexcept {
+ const size_t offset_in_page = offset % PAGE_BYTES;
+ const size_t first_bit = offset_in_page >> BYTES_PER_BIT_SHIFT;
+ const size_t num_bits = std::min(size, PAGE_BYTES) >> BYTES_PER_BIT_SHIFT;
+ const size_t mask = ~u64{0} >> (64 - num_bits);
+ pages[page] |= (~u64{0} & mask) << first_bit;
+ }
+
+ bool IsPageUsed(u64 page, u64 offset, u64 size) const noexcept {
+ const size_t offset_in_page = offset % PAGE_BYTES;
+ const size_t first_bit = offset_in_page >> BYTES_PER_BIT_SHIFT;
+ const size_t num_bits = std::min(size, PAGE_BYTES) >> BYTES_PER_BIT_SHIFT;
+ const size_t mask = ~u64{0} >> (64 - num_bits);
+ const size_t mask2 = (~u64{0} & mask) << first_bit;
+ return (pages[page] & mask2) != 0;
+ }
+
+private:
+ std::vector<u64> pages;
+};
+
+} // namespace VideoCommon
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp
index 02e161270..91f10aec2 100644
--- a/src/video_core/engines/fermi_2d.cpp
+++ b/src/video_core/engines/fermi_2d.cpp
@@ -72,7 +72,7 @@ void Fermi2D::Blit() {
UNIMPLEMENTED_IF_MSG(regs.clip_enable != 0, "Clipped blit enabled");
const auto& args = regs.pixels_from_memory;
- constexpr s64 null_derivate = 1ULL << 32;
+ constexpr s64 null_derivative = 1ULL << 32;
Surface src = regs.src;
const auto bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(src.format));
const bool delegate_to_gpu = src.width > 512 && src.height > 512 && bytes_per_pixel <= 8 &&
@@ -89,7 +89,7 @@ void Fermi2D::Blit() {
.operation = regs.operation,
.filter = args.sample_mode.filter,
.must_accelerate =
- args.du_dx != null_derivate || args.dv_dy != null_derivate || delegate_to_gpu,
+ args.du_dx != null_derivative || args.dv_dy != null_derivative || delegate_to_gpu,
.dst_x0 = args.dst_x0,
.dst_y0 = args.dst_y0,
.dst_x1 = args.dst_x0 + args.dst_width,
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 32d767d85..592c28ba3 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -268,7 +268,7 @@ size_t Maxwell3D::EstimateIndexBufferSize() {
std::numeric_limits<u32>::max()};
const size_t byte_size = regs.index_buffer.FormatSizeInBytes();
const size_t log2_byte_size = Common::Log2Ceil64(byte_size);
- const size_t cap{GetMaxCurrentVertices() * 3 * byte_size};
+ const size_t cap{GetMaxCurrentVertices() * 4 * byte_size};
const size_t lower_cap =
std::min<size_t>(static_cast<size_t>(end_address - start_address), cap);
return std::min<size_t>(
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index c0e6471fe..805a89900 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -86,10 +86,7 @@ public:
uncommitted_operations.emplace_back(std::move(func));
}
pending_operations.emplace_back(std::move(uncommitted_operations));
- {
- std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
- QueueFence(new_fence);
- }
+ QueueFence(new_fence);
if (!delay_fence) {
func();
}
diff --git a/src/video_core/host1x/codecs/codec.cpp b/src/video_core/host1x/codecs/codec.cpp
index dbcf508e5..1030db681 100644
--- a/src/video_core/host1x/codecs/codec.cpp
+++ b/src/video_core/host1x/codecs/codec.cpp
@@ -1,11 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include <algorithm>
-#include <fstream>
-#include <vector>
#include "common/assert.h"
-#include "common/scope_exit.h"
#include "common/settings.h"
#include "video_core/host1x/codecs/codec.h"
#include "video_core/host1x/codecs/h264.h"
@@ -14,242 +10,17 @@
#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
-extern "C" {
-#include <libavfilter/buffersink.h>
-#include <libavfilter/buffersrc.h>
-#include <libavutil/opt.h>
-#ifdef LIBVA_FOUND
-// for querying VAAPI driver information
-#include <libavutil/hwcontext_vaapi.h>
-#endif
-}
-
namespace Tegra {
-namespace {
-constexpr AVPixelFormat PREFERRED_GPU_FMT = AV_PIX_FMT_NV12;
-constexpr AVPixelFormat PREFERRED_CPU_FMT = AV_PIX_FMT_YUV420P;
-constexpr std::array PREFERRED_GPU_DECODERS = {
- AV_HWDEVICE_TYPE_CUDA,
-#ifdef _WIN32
- AV_HWDEVICE_TYPE_D3D11VA,
- AV_HWDEVICE_TYPE_DXVA2,
-#elif defined(__unix__)
- AV_HWDEVICE_TYPE_VAAPI,
- AV_HWDEVICE_TYPE_VDPAU,
-#endif
- // last resort for Linux Flatpak (w/ NVIDIA)
- AV_HWDEVICE_TYPE_VULKAN,
-};
-
-void AVPacketDeleter(AVPacket* ptr) {
- av_packet_free(&ptr);
-}
-
-using AVPacketPtr = std::unique_ptr<AVPacket, decltype(&AVPacketDeleter)>;
-
-AVPixelFormat GetGpuFormat(AVCodecContext* av_codec_ctx, const AVPixelFormat* pix_fmts) {
- for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) {
- if (*p == av_codec_ctx->pix_fmt) {
- return av_codec_ctx->pix_fmt;
- }
- }
- LOG_INFO(Service_NVDRV, "Could not find compatible GPU AV format, falling back to CPU");
- av_buffer_unref(&av_codec_ctx->hw_device_ctx);
- av_codec_ctx->pix_fmt = PREFERRED_CPU_FMT;
- return PREFERRED_CPU_FMT;
-}
-
-// List all the currently available hwcontext in ffmpeg
-std::vector<AVHWDeviceType> ListSupportedContexts() {
- std::vector<AVHWDeviceType> contexts{};
- AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE;
- do {
- current_device_type = av_hwdevice_iterate_types(current_device_type);
- contexts.push_back(current_device_type);
- } while (current_device_type != AV_HWDEVICE_TYPE_NONE);
- return contexts;
-}
-
-} // namespace
-
-void AVFrameDeleter(AVFrame* ptr) {
- av_frame_free(&ptr);
-}
Codec::Codec(Host1x::Host1x& host1x_, const Host1x::NvdecCommon::NvdecRegisters& regs)
: host1x(host1x_), state{regs}, h264_decoder(std::make_unique<Decoder::H264>(host1x)),
vp8_decoder(std::make_unique<Decoder::VP8>(host1x)),
vp9_decoder(std::make_unique<Decoder::VP9>(host1x)) {}
-Codec::~Codec() {
- if (!initialized) {
- return;
- }
- // Free libav memory
- avcodec_free_context(&av_codec_ctx);
- av_buffer_unref(&av_gpu_decoder);
-
- if (filters_initialized) {
- avfilter_graph_free(&av_filter_graph);
- }
-}
-
-bool Codec::CreateGpuAvDevice() {
- static constexpr auto HW_CONFIG_METHOD = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX;
- static const auto supported_contexts = ListSupportedContexts();
- for (const auto& type : PREFERRED_GPU_DECODERS) {
- if (std::none_of(supported_contexts.begin(), supported_contexts.end(),
- [&type](const auto& context) { return context == type; })) {
- LOG_DEBUG(Service_NVDRV, "{} explicitly unsupported", av_hwdevice_get_type_name(type));
- continue;
- }
- // Avoid memory leak from not cleaning up after av_hwdevice_ctx_create
- av_buffer_unref(&av_gpu_decoder);
- const int hwdevice_res = av_hwdevice_ctx_create(&av_gpu_decoder, type, nullptr, nullptr, 0);
- if (hwdevice_res < 0) {
- LOG_DEBUG(Service_NVDRV, "{} av_hwdevice_ctx_create failed {}",
- av_hwdevice_get_type_name(type), hwdevice_res);
- continue;
- }
-#ifdef LIBVA_FOUND
- if (type == AV_HWDEVICE_TYPE_VAAPI) {
- // we need to determine if this is an impersonated VAAPI driver
- AVHWDeviceContext* hwctx =
- static_cast<AVHWDeviceContext*>(static_cast<void*>(av_gpu_decoder->data));
- AVVAAPIDeviceContext* vactx = static_cast<AVVAAPIDeviceContext*>(hwctx->hwctx);
- const char* vendor_name = vaQueryVendorString(vactx->display);
- if (strstr(vendor_name, "VDPAU backend")) {
- // VDPAU impersonated VAAPI impl's are super buggy, we need to skip them
- LOG_DEBUG(Service_NVDRV, "Skipping vdapu impersonated VAAPI driver");
- continue;
- } else {
- // according to some user testing, certain vaapi driver (Intel?) could be buggy
- // so let's log the driver name which may help the developers/supporters
- LOG_DEBUG(Service_NVDRV, "Using VAAPI driver: {}", vendor_name);
- }
- }
-#endif
- for (int i = 0;; i++) {
- const AVCodecHWConfig* config = avcodec_get_hw_config(av_codec, i);
- if (!config) {
- LOG_DEBUG(Service_NVDRV, "{} decoder does not support device type {}.",
- av_codec->name, av_hwdevice_get_type_name(type));
- break;
- }
- if ((config->methods & HW_CONFIG_METHOD) != 0 && config->device_type == type) {
- LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type));
- av_codec_ctx->pix_fmt = config->pix_fmt;
- return true;
- }
- }
- }
- return false;
-}
-
-void Codec::InitializeAvCodecContext() {
- av_codec_ctx = avcodec_alloc_context3(av_codec);
- av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
- av_codec_ctx->thread_count = 0;
- av_codec_ctx->thread_type &= ~FF_THREAD_FRAME;
-}
-
-void Codec::InitializeGpuDecoder() {
- if (!CreateGpuAvDevice()) {
- av_buffer_unref(&av_gpu_decoder);
- return;
- }
- auto* hw_device_ctx = av_buffer_ref(av_gpu_decoder);
- ASSERT_MSG(hw_device_ctx, "av_buffer_ref failed");
- av_codec_ctx->hw_device_ctx = hw_device_ctx;
- av_codec_ctx->get_format = GetGpuFormat;
-}
-
-void Codec::InitializeAvFilters(AVFrame* frame) {
- const AVFilter* buffer_src = avfilter_get_by_name("buffer");
- const AVFilter* buffer_sink = avfilter_get_by_name("buffersink");
- AVFilterInOut* inputs = avfilter_inout_alloc();
- AVFilterInOut* outputs = avfilter_inout_alloc();
- SCOPE_EXIT({
- avfilter_inout_free(&inputs);
- avfilter_inout_free(&outputs);
- });
-
- // Don't know how to get the accurate time_base but it doesn't matter for yadif filter
- // so just use 1/1 to make buffer filter happy
- std::string args = fmt::format("video_size={}x{}:pix_fmt={}:time_base=1/1", frame->width,
- frame->height, frame->format);
-
- av_filter_graph = avfilter_graph_alloc();
- int ret = avfilter_graph_create_filter(&av_filter_src_ctx, buffer_src, "in", args.c_str(),
- nullptr, av_filter_graph);
- if (ret < 0) {
- LOG_ERROR(Service_NVDRV, "avfilter_graph_create_filter source error: {}", ret);
- return;
- }
-
- ret = avfilter_graph_create_filter(&av_filter_sink_ctx, buffer_sink, "out", nullptr, nullptr,
- av_filter_graph);
- if (ret < 0) {
- LOG_ERROR(Service_NVDRV, "avfilter_graph_create_filter sink error: {}", ret);
- return;
- }
-
- inputs->name = av_strdup("out");
- inputs->filter_ctx = av_filter_sink_ctx;
- inputs->pad_idx = 0;
- inputs->next = nullptr;
-
- outputs->name = av_strdup("in");
- outputs->filter_ctx = av_filter_src_ctx;
- outputs->pad_idx = 0;
- outputs->next = nullptr;
-
- const char* description = "yadif=1:-1:0";
- ret = avfilter_graph_parse_ptr(av_filter_graph, description, &inputs, &outputs, nullptr);
- if (ret < 0) {
- LOG_ERROR(Service_NVDRV, "avfilter_graph_parse_ptr error: {}", ret);
- return;
- }
-
- ret = avfilter_graph_config(av_filter_graph, nullptr);
- if (ret < 0) {
- LOG_ERROR(Service_NVDRV, "avfilter_graph_config error: {}", ret);
- return;
- }
-
- filters_initialized = true;
-}
+Codec::~Codec() = default;
void Codec::Initialize() {
- const AVCodecID codec = [&] {
- switch (current_codec) {
- case Host1x::NvdecCommon::VideoCodec::H264:
- return AV_CODEC_ID_H264;
- case Host1x::NvdecCommon::VideoCodec::VP8:
- return AV_CODEC_ID_VP8;
- case Host1x::NvdecCommon::VideoCodec::VP9:
- return AV_CODEC_ID_VP9;
- default:
- UNIMPLEMENTED_MSG("Unknown codec {}", current_codec);
- return AV_CODEC_ID_NONE;
- }
- }();
- av_codec = avcodec_find_decoder(codec);
-
- InitializeAvCodecContext();
- if (Settings::values.nvdec_emulation.GetValue() == Settings::NvdecEmulation::Gpu) {
- InitializeGpuDecoder();
- }
- if (const int res = avcodec_open2(av_codec_ctx, av_codec, nullptr); res < 0) {
- LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed with result {}", res);
- avcodec_free_context(&av_codec_ctx);
- av_buffer_unref(&av_gpu_decoder);
- return;
- }
- if (!av_codec_ctx->hw_device_ctx) {
- LOG_INFO(Service_NVDRV, "Using FFmpeg software decoding");
- }
- initialized = true;
+ initialized = decode_api.Initialize(current_codec);
}
void Codec::SetTargetCodec(Host1x::NvdecCommon::VideoCodec codec) {
@@ -264,14 +35,18 @@ void Codec::Decode() {
if (is_first_frame) {
Initialize();
}
+
if (!initialized) {
return;
}
+
+ // Assemble bitstream.
bool vp9_hidden_frame = false;
- const auto& frame_data = [&]() {
+ size_t configuration_size = 0;
+ const auto packet_data = [&]() {
switch (current_codec) {
case Tegra::Host1x::NvdecCommon::VideoCodec::H264:
- return h264_decoder->ComposeFrame(state, is_first_frame);
+ return h264_decoder->ComposeFrame(state, &configuration_size, is_first_frame);
case Tegra::Host1x::NvdecCommon::VideoCodec::VP8:
return vp8_decoder->ComposeFrame(state);
case Tegra::Host1x::NvdecCommon::VideoCodec::VP9:
@@ -283,89 +58,35 @@ void Codec::Decode() {
return std::span<const u8>{};
}
}();
- AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter};
- if (!packet) {
- LOG_ERROR(Service_NVDRV, "av_packet_alloc failed");
- return;
- }
- packet->data = const_cast<u8*>(frame_data.data());
- packet->size = static_cast<s32>(frame_data.size());
- if (const int res = avcodec_send_packet(av_codec_ctx, packet.get()); res != 0) {
- LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", res);
+
+ // Send assembled bitstream to decoder.
+ if (!decode_api.SendPacket(packet_data, configuration_size)) {
return;
}
- // Only receive/store visible frames
+
+ // Only receive/store visible frames.
if (vp9_hidden_frame) {
return;
}
- AVFramePtr initial_frame{av_frame_alloc(), AVFrameDeleter};
- AVFramePtr final_frame{nullptr, AVFrameDeleter};
- ASSERT_MSG(initial_frame, "av_frame_alloc initial_frame failed");
- if (const int ret = avcodec_receive_frame(av_codec_ctx, initial_frame.get()); ret) {
- LOG_DEBUG(Service_NVDRV, "avcodec_receive_frame error {}", ret);
- return;
- }
- if (initial_frame->width == 0 || initial_frame->height == 0) {
- LOG_WARNING(Service_NVDRV, "Zero width or height in frame");
- return;
- }
- bool is_interlaced = initial_frame->interlaced_frame != 0;
- if (av_codec_ctx->hw_device_ctx) {
- final_frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
- ASSERT_MSG(final_frame, "av_frame_alloc final_frame failed");
- // Can't use AV_PIX_FMT_YUV420P and share code with software decoding in vic.cpp
- // because Intel drivers crash unless using AV_PIX_FMT_NV12
- final_frame->format = PREFERRED_GPU_FMT;
- const int ret = av_hwframe_transfer_data(final_frame.get(), initial_frame.get(), 0);
- ASSERT_MSG(!ret, "av_hwframe_transfer_data error {}", ret);
- } else {
- final_frame = std::move(initial_frame);
- }
- if (final_frame->format != PREFERRED_CPU_FMT && final_frame->format != PREFERRED_GPU_FMT) {
- UNIMPLEMENTED_MSG("Unexpected video format: {}", final_frame->format);
- return;
- }
- if (!is_interlaced) {
- av_frames.push(std::move(final_frame));
- } else {
- if (!filters_initialized) {
- InitializeAvFilters(final_frame.get());
- }
- if (const int ret = av_buffersrc_add_frame_flags(av_filter_src_ctx, final_frame.get(),
- AV_BUFFERSRC_FLAG_KEEP_REF);
- ret) {
- LOG_DEBUG(Service_NVDRV, "av_buffersrc_add_frame_flags error {}", ret);
- return;
- }
- while (true) {
- auto filter_frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
- int ret = av_buffersink_get_frame(av_filter_sink_ctx, filter_frame.get());
+ // Receive output frames from decoder.
+ decode_api.ReceiveFrames(frames);
- if (ret == AVERROR(EAGAIN) || ret == AVERROR(AVERROR_EOF))
- break;
- if (ret < 0) {
- LOG_DEBUG(Service_NVDRV, "av_buffersink_get_frame error {}", ret);
- return;
- }
-
- av_frames.push(std::move(filter_frame));
- }
- }
- while (av_frames.size() > 10) {
- LOG_TRACE(Service_NVDRV, "av_frames.push overflow dropped frame");
- av_frames.pop();
+ while (frames.size() > 10) {
+ LOG_DEBUG(HW_GPU, "ReceiveFrames overflow, dropped frame");
+ frames.pop();
}
}
-AVFramePtr Codec::GetCurrentFrame() {
+std::unique_ptr<FFmpeg::Frame> Codec::GetCurrentFrame() {
// Sometimes VIC will request more frames than have been decoded.
- // in this case, return a nullptr and don't overwrite previous frame data
- if (av_frames.empty()) {
- return AVFramePtr{nullptr, AVFrameDeleter};
+ // in this case, return a blank frame and don't overwrite previous data.
+ if (frames.empty()) {
+ return {};
}
- AVFramePtr frame = std::move(av_frames.front());
- av_frames.pop();
+
+ auto frame = std::move(frames.front());
+ frames.pop();
return frame;
}
diff --git a/src/video_core/host1x/codecs/codec.h b/src/video_core/host1x/codecs/codec.h
index 06fe00a4b..f700ae129 100644
--- a/src/video_core/host1x/codecs/codec.h
+++ b/src/video_core/host1x/codecs/codec.h
@@ -4,28 +4,15 @@
#pragma once
#include <memory>
+#include <optional>
#include <string_view>
#include <queue>
#include "common/common_types.h"
+#include "video_core/host1x/ffmpeg/ffmpeg.h"
#include "video_core/host1x/nvdec_common.h"
-extern "C" {
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-#endif
-#include <libavcodec/avcodec.h>
-#include <libavfilter/avfilter.h>
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-}
-
namespace Tegra {
-void AVFrameDeleter(AVFrame* ptr);
-using AVFramePtr = std::unique_ptr<AVFrame, decltype(&AVFrameDeleter)>;
-
namespace Decoder {
class H264;
class VP8;
@@ -51,7 +38,7 @@ public:
void Decode();
/// Returns next decoded frame
- [[nodiscard]] AVFramePtr GetCurrentFrame();
+ [[nodiscard]] std::unique_ptr<FFmpeg::Frame> GetCurrentFrame();
/// Returns the value of current_codec
[[nodiscard]] Host1x::NvdecCommon::VideoCodec GetCurrentCodec() const;
@@ -60,25 +47,9 @@ public:
[[nodiscard]] std::string_view GetCurrentCodecName() const;
private:
- void InitializeAvCodecContext();
-
- void InitializeAvFilters(AVFrame* frame);
-
- void InitializeGpuDecoder();
-
- bool CreateGpuAvDevice();
-
bool initialized{};
- bool filters_initialized{};
Host1x::NvdecCommon::VideoCodec current_codec{Host1x::NvdecCommon::VideoCodec::None};
-
- const AVCodec* av_codec{nullptr};
- AVCodecContext* av_codec_ctx{nullptr};
- AVBufferRef* av_gpu_decoder{nullptr};
-
- AVFilterContext* av_filter_src_ctx{nullptr};
- AVFilterContext* av_filter_sink_ctx{nullptr};
- AVFilterGraph* av_filter_graph{nullptr};
+ FFmpeg::DecodeApi decode_api;
Host1x::Host1x& host1x;
const Host1x::NvdecCommon::NvdecRegisters& state;
@@ -86,7 +57,7 @@ private:
std::unique_ptr<Decoder::VP8> vp8_decoder;
std::unique_ptr<Decoder::VP9> vp9_decoder;
- std::queue<AVFramePtr> av_frames{};
+ std::queue<std::unique_ptr<FFmpeg::Frame>> frames{};
};
} // namespace Tegra
diff --git a/src/video_core/host1x/codecs/h264.cpp b/src/video_core/host1x/codecs/h264.cpp
index ece79b1e2..309a7f1d5 100644
--- a/src/video_core/host1x/codecs/h264.cpp
+++ b/src/video_core/host1x/codecs/h264.cpp
@@ -30,7 +30,7 @@ H264::H264(Host1x::Host1x& host1x_) : host1x{host1x_} {}
H264::~H264() = default;
std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state,
- bool is_first_frame) {
+ size_t* out_configuration_size, bool is_first_frame) {
H264DecoderContext context;
host1x.MemoryManager().ReadBlock(state.picture_info_offset, &context,
sizeof(H264DecoderContext));
@@ -39,6 +39,7 @@ std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters
if (!is_first_frame && frame_number != 0) {
frame.resize_destructive(context.stream_len);
host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.data(), frame.size());
+ *out_configuration_size = 0;
return frame;
}
@@ -157,6 +158,7 @@ std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters
frame.resize(encoded_header.size() + context.stream_len);
std::memcpy(frame.data(), encoded_header.data(), encoded_header.size());
+ *out_configuration_size = encoded_header.size();
host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset,
frame.data() + encoded_header.size(), context.stream_len);
diff --git a/src/video_core/host1x/codecs/h264.h b/src/video_core/host1x/codecs/h264.h
index d6b556322..1deaf4632 100644
--- a/src/video_core/host1x/codecs/h264.h
+++ b/src/video_core/host1x/codecs/h264.h
@@ -67,6 +67,7 @@ public:
/// Compose the H264 frame for FFmpeg decoding
[[nodiscard]] std::span<const u8> ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state,
+ size_t* out_configuration_size,
bool is_first_frame = false);
private:
diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp
new file mode 100644
index 000000000..dcd07e6d2
--- /dev/null
+++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp
@@ -0,0 +1,419 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "common/scope_exit.h"
+#include "common/settings.h"
+#include "video_core/host1x/ffmpeg/ffmpeg.h"
+
+extern "C" {
+#ifdef LIBVA_FOUND
+// for querying VAAPI driver information
+#include <libavutil/hwcontext_vaapi.h>
+#endif
+}
+
+namespace FFmpeg {
+
+namespace {
+
+constexpr AVPixelFormat PreferredGpuFormat = AV_PIX_FMT_NV12;
+constexpr AVPixelFormat PreferredCpuFormat = AV_PIX_FMT_YUV420P;
+constexpr std::array PreferredGpuDecoders = {
+ AV_HWDEVICE_TYPE_CUDA,
+#ifdef _WIN32
+ AV_HWDEVICE_TYPE_D3D11VA,
+ AV_HWDEVICE_TYPE_DXVA2,
+#elif defined(__unix__)
+ AV_HWDEVICE_TYPE_VAAPI,
+ AV_HWDEVICE_TYPE_VDPAU,
+#endif
+ // last resort for Linux Flatpak (w/ NVIDIA)
+ AV_HWDEVICE_TYPE_VULKAN,
+};
+
+AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) {
+ for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) {
+ if (*p == codec_context->pix_fmt) {
+ return codec_context->pix_fmt;
+ }
+ }
+
+ LOG_INFO(HW_GPU, "Could not find compatible GPU AV format, falling back to CPU");
+ av_buffer_unref(&codec_context->hw_device_ctx);
+
+ codec_context->pix_fmt = PreferredCpuFormat;
+ return codec_context->pix_fmt;
+}
+
+std::string AVError(int errnum) {
+ char errbuf[AV_ERROR_MAX_STRING_SIZE] = {};
+ av_make_error_string(errbuf, sizeof(errbuf) - 1, errnum);
+ return errbuf;
+}
+
+} // namespace
+
+Packet::Packet(std::span<const u8> data) {
+ m_packet = av_packet_alloc();
+ m_packet->data = const_cast<u8*>(data.data());
+ m_packet->size = static_cast<s32>(data.size());
+}
+
+Packet::~Packet() {
+ av_packet_free(&m_packet);
+}
+
+Frame::Frame() {
+ m_frame = av_frame_alloc();
+}
+
+Frame::~Frame() {
+ av_frame_free(&m_frame);
+}
+
+Decoder::Decoder(Tegra::Host1x::NvdecCommon::VideoCodec codec) {
+ const AVCodecID av_codec = [&] {
+ switch (codec) {
+ case Tegra::Host1x::NvdecCommon::VideoCodec::H264:
+ return AV_CODEC_ID_H264;
+ case Tegra::Host1x::NvdecCommon::VideoCodec::VP8:
+ return AV_CODEC_ID_VP8;
+ case Tegra::Host1x::NvdecCommon::VideoCodec::VP9:
+ return AV_CODEC_ID_VP9;
+ default:
+ UNIMPLEMENTED_MSG("Unknown codec {}", codec);
+ return AV_CODEC_ID_NONE;
+ }
+ }();
+
+ m_codec = avcodec_find_decoder(av_codec);
+}
+
+bool Decoder::SupportsDecodingOnDevice(AVPixelFormat* out_pix_fmt, AVHWDeviceType type) const {
+ for (int i = 0;; i++) {
+ const AVCodecHWConfig* config = avcodec_get_hw_config(m_codec, i);
+ if (!config) {
+ LOG_DEBUG(HW_GPU, "{} decoder does not support device type {}", m_codec->name,
+ av_hwdevice_get_type_name(type));
+ break;
+ }
+ if ((config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&
+ config->device_type == type) {
+ LOG_INFO(HW_GPU, "Using {} GPU decoder", av_hwdevice_get_type_name(type));
+ *out_pix_fmt = config->pix_fmt;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::vector<AVHWDeviceType> HardwareContext::GetSupportedDeviceTypes() {
+ std::vector<AVHWDeviceType> types;
+ AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE;
+
+ while (true) {
+ current_device_type = av_hwdevice_iterate_types(current_device_type);
+ if (current_device_type == AV_HWDEVICE_TYPE_NONE) {
+ return types;
+ }
+
+ types.push_back(current_device_type);
+ }
+}
+
+HardwareContext::~HardwareContext() {
+ av_buffer_unref(&m_gpu_decoder);
+}
+
+bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context,
+ const Decoder& decoder) {
+ const auto supported_types = GetSupportedDeviceTypes();
+ for (const auto type : PreferredGpuDecoders) {
+ AVPixelFormat hw_pix_fmt;
+
+ if (std::ranges::find(supported_types, type) == supported_types.end()) {
+ LOG_DEBUG(HW_GPU, "{} explicitly unsupported", av_hwdevice_get_type_name(type));
+ continue;
+ }
+
+ if (!this->InitializeWithType(type)) {
+ continue;
+ }
+
+ if (decoder.SupportsDecodingOnDevice(&hw_pix_fmt, type)) {
+ decoder_context.InitializeHardwareDecoder(*this, hw_pix_fmt);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool HardwareContext::InitializeWithType(AVHWDeviceType type) {
+ av_buffer_unref(&m_gpu_decoder);
+
+ if (const int ret = av_hwdevice_ctx_create(&m_gpu_decoder, type, nullptr, nullptr, 0);
+ ret < 0) {
+ LOG_DEBUG(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type),
+ AVError(ret));
+ return false;
+ }
+
+#ifdef LIBVA_FOUND
+ if (type == AV_HWDEVICE_TYPE_VAAPI) {
+ // We need to determine if this is an impersonated VAAPI driver.
+ auto* hwctx = reinterpret_cast<AVHWDeviceContext*>(m_gpu_decoder->data);
+ auto* vactx = static_cast<AVVAAPIDeviceContext*>(hwctx->hwctx);
+ const char* vendor_name = vaQueryVendorString(vactx->display);
+ if (strstr(vendor_name, "VDPAU backend")) {
+ // VDPAU impersonated VAAPI impls are super buggy, we need to skip them.
+ LOG_DEBUG(HW_GPU, "Skipping VDPAU impersonated VAAPI driver");
+ return false;
+ } else {
+ // According to some user testing, certain VAAPI drivers (Intel?) could be buggy.
+ // Log the driver name just in case.
+ LOG_DEBUG(HW_GPU, "Using VAAPI driver: {}", vendor_name);
+ }
+ }
+#endif
+
+ return true;
+}
+
+DecoderContext::DecoderContext(const Decoder& decoder) {
+ m_codec_context = avcodec_alloc_context3(decoder.GetCodec());
+ av_opt_set(m_codec_context->priv_data, "tune", "zerolatency", 0);
+ m_codec_context->thread_count = 0;
+ m_codec_context->thread_type &= ~FF_THREAD_FRAME;
+}
+
+DecoderContext::~DecoderContext() {
+ av_buffer_unref(&m_codec_context->hw_device_ctx);
+ avcodec_free_context(&m_codec_context);
+}
+
+void DecoderContext::InitializeHardwareDecoder(const HardwareContext& context,
+ AVPixelFormat hw_pix_fmt) {
+ m_codec_context->hw_device_ctx = av_buffer_ref(context.GetBufferRef());
+ m_codec_context->get_format = GetGpuFormat;
+ m_codec_context->pix_fmt = hw_pix_fmt;
+}
+
+bool DecoderContext::OpenContext(const Decoder& decoder) {
+ if (const int ret = avcodec_open2(m_codec_context, decoder.GetCodec(), nullptr); ret < 0) {
+ LOG_ERROR(HW_GPU, "avcodec_open2 error: {}", AVError(ret));
+ return false;
+ }
+
+ if (!m_codec_context->hw_device_ctx) {
+ LOG_INFO(HW_GPU, "Using FFmpeg software decoding");
+ }
+
+ return true;
+}
+
+bool DecoderContext::SendPacket(const Packet& packet) {
+ if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0) {
+ LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret));
+ return false;
+ }
+
+ return true;
+}
+
+std::unique_ptr<Frame> DecoderContext::ReceiveFrame(bool* out_is_interlaced) {
+ auto dst_frame = std::make_unique<Frame>();
+
+ const auto ReceiveImpl = [&](AVFrame* frame) {
+ if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0) {
+ LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret));
+ return false;
+ }
+
+ *out_is_interlaced = frame->interlaced_frame != 0;
+ return true;
+ };
+
+ if (m_codec_context->hw_device_ctx) {
+ // If we have a hardware context, make a separate frame here to receive the
+ // hardware result before sending it to the output.
+ Frame intermediate_frame;
+
+ if (!ReceiveImpl(intermediate_frame.GetFrame())) {
+ return {};
+ }
+
+ dst_frame->SetFormat(PreferredGpuFormat);
+ if (const int ret =
+ av_hwframe_transfer_data(dst_frame->GetFrame(), intermediate_frame.GetFrame(), 0);
+ ret < 0) {
+ LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret));
+ return {};
+ }
+ } else {
+ // Otherwise, decode the frame as normal.
+ if (!ReceiveImpl(dst_frame->GetFrame())) {
+ return {};
+ }
+ }
+
+ return dst_frame;
+}
+
+DeinterlaceFilter::DeinterlaceFilter(const Frame& frame) {
+ const AVFilter* buffer_src = avfilter_get_by_name("buffer");
+ const AVFilter* buffer_sink = avfilter_get_by_name("buffersink");
+ AVFilterInOut* inputs = avfilter_inout_alloc();
+ AVFilterInOut* outputs = avfilter_inout_alloc();
+ SCOPE_EXIT({
+ avfilter_inout_free(&inputs);
+ avfilter_inout_free(&outputs);
+ });
+
+ // Don't know how to get the accurate time_base but it doesn't matter for yadif filter
+ // so just use 1/1 to make buffer filter happy
+ std::string args = fmt::format("video_size={}x{}:pix_fmt={}:time_base=1/1", frame.GetWidth(),
+ frame.GetHeight(), static_cast<int>(frame.GetPixelFormat()));
+
+ m_filter_graph = avfilter_graph_alloc();
+ int ret = avfilter_graph_create_filter(&m_source_context, buffer_src, "in", args.c_str(),
+ nullptr, m_filter_graph);
+ if (ret < 0) {
+ LOG_ERROR(HW_GPU, "avfilter_graph_create_filter source error: {}", AVError(ret));
+ return;
+ }
+
+ ret = avfilter_graph_create_filter(&m_sink_context, buffer_sink, "out", nullptr, nullptr,
+ m_filter_graph);
+ if (ret < 0) {
+ LOG_ERROR(HW_GPU, "avfilter_graph_create_filter sink error: {}", AVError(ret));
+ return;
+ }
+
+ inputs->name = av_strdup("out");
+ inputs->filter_ctx = m_sink_context;
+ inputs->pad_idx = 0;
+ inputs->next = nullptr;
+
+ outputs->name = av_strdup("in");
+ outputs->filter_ctx = m_source_context;
+ outputs->pad_idx = 0;
+ outputs->next = nullptr;
+
+ const char* description = "yadif=1:-1:0";
+ ret = avfilter_graph_parse_ptr(m_filter_graph, description, &inputs, &outputs, nullptr);
+ if (ret < 0) {
+ LOG_ERROR(HW_GPU, "avfilter_graph_parse_ptr error: {}", AVError(ret));
+ return;
+ }
+
+ ret = avfilter_graph_config(m_filter_graph, nullptr);
+ if (ret < 0) {
+ LOG_ERROR(HW_GPU, "avfilter_graph_config error: {}", AVError(ret));
+ return;
+ }
+
+ m_initialized = true;
+}
+
+bool DeinterlaceFilter::AddSourceFrame(const Frame& frame) {
+ if (const int ret = av_buffersrc_add_frame_flags(m_source_context, frame.GetFrame(),
+ AV_BUFFERSRC_FLAG_KEEP_REF);
+ ret < 0) {
+ LOG_ERROR(HW_GPU, "av_buffersrc_add_frame_flags error: {}", AVError(ret));
+ return false;
+ }
+
+ return true;
+}
+
+std::unique_ptr<Frame> DeinterlaceFilter::DrainSinkFrame() {
+ auto dst_frame = std::make_unique<Frame>();
+ const int ret = av_buffersink_get_frame(m_sink_context, dst_frame->GetFrame());
+
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR(AVERROR_EOF)) {
+ return {};
+ }
+
+ if (ret < 0) {
+ LOG_ERROR(HW_GPU, "av_buffersink_get_frame error: {}", AVError(ret));
+ return {};
+ }
+
+ return dst_frame;
+}
+
+DeinterlaceFilter::~DeinterlaceFilter() {
+ avfilter_graph_free(&m_filter_graph);
+}
+
+void DecodeApi::Reset() {
+ m_deinterlace_filter.reset();
+ m_hardware_context.reset();
+ m_decoder_context.reset();
+ m_decoder.reset();
+}
+
+bool DecodeApi::Initialize(Tegra::Host1x::NvdecCommon::VideoCodec codec) {
+ this->Reset();
+ m_decoder.emplace(codec);
+ m_decoder_context.emplace(*m_decoder);
+
+ // Enable GPU decoding if requested.
+ if (Settings::values.nvdec_emulation.GetValue() == Settings::NvdecEmulation::Gpu) {
+ m_hardware_context.emplace();
+ m_hardware_context->InitializeForDecoder(*m_decoder_context, *m_decoder);
+ }
+
+ // Open the decoder context.
+ if (!m_decoder_context->OpenContext(*m_decoder)) {
+ this->Reset();
+ return false;
+ }
+
+ return true;
+}
+
+bool DecodeApi::SendPacket(std::span<const u8> packet_data, size_t configuration_size) {
+ FFmpeg::Packet packet(packet_data);
+ return m_decoder_context->SendPacket(packet);
+}
+
+void DecodeApi::ReceiveFrames(std::queue<std::unique_ptr<Frame>>& frame_queue) {
+ // Receive raw frame from decoder.
+ bool is_interlaced;
+ auto frame = m_decoder_context->ReceiveFrame(&is_interlaced);
+ if (!frame) {
+ return;
+ }
+
+ if (!is_interlaced) {
+ // If the frame is not interlaced, we can pend it now.
+ frame_queue.push(std::move(frame));
+ } else {
+ // Create the deinterlacer if needed.
+ if (!m_deinterlace_filter) {
+ m_deinterlace_filter.emplace(*frame);
+ }
+
+ // Add the frame we just received.
+ if (!m_deinterlace_filter->AddSourceFrame(*frame)) {
+ return;
+ }
+
+ // Pend output fields.
+ while (true) {
+ auto filter_frame = m_deinterlace_filter->DrainSinkFrame();
+ if (!filter_frame) {
+ break;
+ }
+
+ frame_queue.push(std::move(filter_frame));
+ }
+ }
+}
+
+} // namespace FFmpeg
diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.h b/src/video_core/host1x/ffmpeg/ffmpeg.h
new file mode 100644
index 000000000..1de0bbd83
--- /dev/null
+++ b/src/video_core/host1x/ffmpeg/ffmpeg.h
@@ -0,0 +1,213 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <memory>
+#include <optional>
+#include <span>
+#include <vector>
+#include <queue>
+
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+#include "video_core/host1x/nvdec_common.h"
+
+extern "C" {
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+
+#include <libavcodec/avcodec.h>
+#include <libavfilter/avfilter.h>
+#include <libavfilter/buffersink.h>
+#include <libavfilter/buffersrc.h>
+#include <libavutil/avutil.h>
+#include <libavutil/opt.h>
+
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+}
+
+namespace FFmpeg {
+
+class Packet;
+class Frame;
+class Decoder;
+class HardwareContext;
+class DecoderContext;
+class DeinterlaceFilter;
+
+// Wraps an AVPacket, a container for compressed bitstream data.
+class Packet {
+public:
+ YUZU_NON_COPYABLE(Packet);
+ YUZU_NON_MOVEABLE(Packet);
+
+ explicit Packet(std::span<const u8> data);
+ ~Packet();
+
+ AVPacket* GetPacket() const {
+ return m_packet;
+ }
+
+private:
+ AVPacket* m_packet{};
+};
+
+// Wraps an AVFrame, a container for audio and video stream data.
+class Frame {
+public:
+ YUZU_NON_COPYABLE(Frame);
+ YUZU_NON_MOVEABLE(Frame);
+
+ explicit Frame();
+ ~Frame();
+
+ int GetWidth() const {
+ return m_frame->width;
+ }
+
+ int GetHeight() const {
+ return m_frame->height;
+ }
+
+ AVPixelFormat GetPixelFormat() const {
+ return static_cast<AVPixelFormat>(m_frame->format);
+ }
+
+ int GetStride(int plane) const {
+ return m_frame->linesize[plane];
+ }
+
+ int* GetStrides() const {
+ return m_frame->linesize;
+ }
+
+ u8* GetData(int plane) const {
+ return m_frame->data[plane];
+ }
+
+ u8** GetPlanes() const {
+ return m_frame->data;
+ }
+
+ void SetFormat(int format) {
+ m_frame->format = format;
+ }
+
+ AVFrame* GetFrame() const {
+ return m_frame;
+ }
+
+private:
+ AVFrame* m_frame{};
+};
+
+// Wraps an AVCodec, a type containing information about a codec.
+class Decoder {
+public:
+ YUZU_NON_COPYABLE(Decoder);
+ YUZU_NON_MOVEABLE(Decoder);
+
+ explicit Decoder(Tegra::Host1x::NvdecCommon::VideoCodec codec);
+ ~Decoder() = default;
+
+ bool SupportsDecodingOnDevice(AVPixelFormat* out_pix_fmt, AVHWDeviceType type) const;
+
+ const AVCodec* GetCodec() const {
+ return m_codec;
+ }
+
+private:
+ const AVCodec* m_codec{};
+};
+
+// Wraps AVBufferRef for an accelerated decoder.
+class HardwareContext {
+public:
+ YUZU_NON_COPYABLE(HardwareContext);
+ YUZU_NON_MOVEABLE(HardwareContext);
+
+ static std::vector<AVHWDeviceType> GetSupportedDeviceTypes();
+
+ explicit HardwareContext() = default;
+ ~HardwareContext();
+
+ bool InitializeForDecoder(DecoderContext& decoder_context, const Decoder& decoder);
+
+ AVBufferRef* GetBufferRef() const {
+ return m_gpu_decoder;
+ }
+
+private:
+ bool InitializeWithType(AVHWDeviceType type);
+
+ AVBufferRef* m_gpu_decoder{};
+};
+
+// Wraps an AVCodecContext.
+class DecoderContext {
+public:
+ YUZU_NON_COPYABLE(DecoderContext);
+ YUZU_NON_MOVEABLE(DecoderContext);
+
+ explicit DecoderContext(const Decoder& decoder);
+ ~DecoderContext();
+
+ void InitializeHardwareDecoder(const HardwareContext& context, AVPixelFormat hw_pix_fmt);
+ bool OpenContext(const Decoder& decoder);
+ bool SendPacket(const Packet& packet);
+ std::unique_ptr<Frame> ReceiveFrame(bool* out_is_interlaced);
+
+ AVCodecContext* GetCodecContext() const {
+ return m_codec_context;
+ }
+
+private:
+ AVCodecContext* m_codec_context{};
+};
+
+// Wraps an AVFilterGraph.
+class DeinterlaceFilter {
+public:
+ YUZU_NON_COPYABLE(DeinterlaceFilter);
+ YUZU_NON_MOVEABLE(DeinterlaceFilter);
+
+ explicit DeinterlaceFilter(const Frame& frame);
+ ~DeinterlaceFilter();
+
+ bool AddSourceFrame(const Frame& frame);
+ std::unique_ptr<Frame> DrainSinkFrame();
+
+private:
+ AVFilterGraph* m_filter_graph{};
+ AVFilterContext* m_source_context{};
+ AVFilterContext* m_sink_context{};
+ bool m_initialized{};
+};
+
+class DecodeApi {
+public:
+ YUZU_NON_COPYABLE(DecodeApi);
+ YUZU_NON_MOVEABLE(DecodeApi);
+
+ DecodeApi() = default;
+ ~DecodeApi() = default;
+
+ bool Initialize(Tegra::Host1x::NvdecCommon::VideoCodec codec);
+ void Reset();
+
+ bool SendPacket(std::span<const u8> packet_data, size_t configuration_size);
+ void ReceiveFrames(std::queue<std::unique_ptr<Frame>>& frame_queue);
+
+private:
+ std::optional<FFmpeg::Decoder> m_decoder;
+ std::optional<FFmpeg::DecoderContext> m_decoder_context;
+ std::optional<FFmpeg::HardwareContext> m_hardware_context;
+ std::optional<FFmpeg::DeinterlaceFilter> m_deinterlace_filter;
+};
+
+} // namespace FFmpeg
diff --git a/src/video_core/host1x/nvdec.cpp b/src/video_core/host1x/nvdec.cpp
index a4bd5b79f..b8f5866d3 100644
--- a/src/video_core/host1x/nvdec.cpp
+++ b/src/video_core/host1x/nvdec.cpp
@@ -28,7 +28,7 @@ void Nvdec::ProcessMethod(u32 method, u32 argument) {
}
}
-AVFramePtr Nvdec::GetFrame() {
+std::unique_ptr<FFmpeg::Frame> Nvdec::GetFrame() {
return codec->GetCurrentFrame();
}
diff --git a/src/video_core/host1x/nvdec.h b/src/video_core/host1x/nvdec.h
index 3949d5181..ddddb8d28 100644
--- a/src/video_core/host1x/nvdec.h
+++ b/src/video_core/host1x/nvdec.h
@@ -23,7 +23,7 @@ public:
void ProcessMethod(u32 method, u32 argument);
/// Return most recently decoded frame
- [[nodiscard]] AVFramePtr GetFrame();
+ [[nodiscard]] std::unique_ptr<FFmpeg::Frame> GetFrame();
private:
/// Invoke codec to decode a frame
diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp
index 10d7ef884..2a5eba415 100644
--- a/src/video_core/host1x/vic.cpp
+++ b/src/video_core/host1x/vic.cpp
@@ -82,27 +82,26 @@ void Vic::Execute() {
return;
}
const VicConfig config{host1x.MemoryManager().Read<u64>(config_struct_address + 0x20)};
- const AVFramePtr frame_ptr = nvdec_processor->GetFrame();
- const auto* frame = frame_ptr.get();
+ auto frame = nvdec_processor->GetFrame();
if (!frame) {
return;
}
const u64 surface_width = config.surface_width_minus1 + 1;
const u64 surface_height = config.surface_height_minus1 + 1;
- if (static_cast<u64>(frame->width) != surface_width ||
- static_cast<u64>(frame->height) != surface_height) {
+ if (static_cast<u64>(frame->GetWidth()) != surface_width ||
+ static_cast<u64>(frame->GetHeight()) != surface_height) {
// TODO: Properly support multiple video streams with differing frame dimensions
LOG_WARNING(Service_NVDRV, "Frame dimensions {}x{} don't match surface dimensions {}x{}",
- frame->width, frame->height, surface_width, surface_height);
+ frame->GetWidth(), frame->GetHeight(), surface_width, surface_height);
}
switch (config.pixel_format) {
case VideoPixelFormat::RGBA8:
case VideoPixelFormat::BGRA8:
case VideoPixelFormat::RGBX8:
- WriteRGBFrame(frame, config);
+ WriteRGBFrame(std::move(frame), config);
break;
case VideoPixelFormat::YUV420:
- WriteYUVFrame(frame, config);
+ WriteYUVFrame(std::move(frame), config);
break;
default:
UNIMPLEMENTED_MSG("Unknown video pixel format {:X}", config.pixel_format.Value());
@@ -110,10 +109,14 @@ void Vic::Execute() {
}
}
-void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
+void Vic::WriteRGBFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config) {
LOG_TRACE(Service_NVDRV, "Writing RGB Frame");
- if (!scaler_ctx || frame->width != scaler_width || frame->height != scaler_height) {
+ const auto frame_width = frame->GetWidth();
+ const auto frame_height = frame->GetHeight();
+ const auto frame_format = frame->GetPixelFormat();
+
+ if (!scaler_ctx || frame_width != scaler_width || frame_height != scaler_height) {
const AVPixelFormat target_format = [pixel_format = config.pixel_format]() {
switch (pixel_format) {
case VideoPixelFormat::RGBA8:
@@ -129,27 +132,26 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
sws_freeContext(scaler_ctx);
// Frames are decoded into either YUV420 or NV12 formats. Convert to desired RGB format
- scaler_ctx = sws_getContext(frame->width, frame->height,
- static_cast<AVPixelFormat>(frame->format), frame->width,
- frame->height, target_format, 0, nullptr, nullptr, nullptr);
- scaler_width = frame->width;
- scaler_height = frame->height;
+ scaler_ctx = sws_getContext(frame_width, frame_height, frame_format, frame_width,
+ frame_height, target_format, 0, nullptr, nullptr, nullptr);
+ scaler_width = frame_width;
+ scaler_height = frame_height;
converted_frame_buffer.reset();
}
if (!converted_frame_buffer) {
- const size_t frame_size = frame->width * frame->height * 4;
+ const size_t frame_size = frame_width * frame_height * 4;
converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(frame_size)), av_free};
}
- const std::array<int, 4> converted_stride{frame->width * 4, frame->height * 4, 0, 0};
+ const std::array<int, 4> converted_stride{frame_width * 4, frame_height * 4, 0, 0};
u8* const converted_frame_buf_addr{converted_frame_buffer.get()};
- sws_scale(scaler_ctx, frame->data, frame->linesize, 0, frame->height, &converted_frame_buf_addr,
- converted_stride.data());
+ sws_scale(scaler_ctx, frame->GetPlanes(), frame->GetStrides(), 0, frame_height,
+ &converted_frame_buf_addr, converted_stride.data());
// Use the minimum of surface/frame dimensions to avoid buffer overflow.
const u32 surface_width = static_cast<u32>(config.surface_width_minus1) + 1;
const u32 surface_height = static_cast<u32>(config.surface_height_minus1) + 1;
- const u32 width = std::min(surface_width, static_cast<u32>(frame->width));
- const u32 height = std::min(surface_height, static_cast<u32>(frame->height));
+ const u32 width = std::min(surface_width, static_cast<u32>(frame_width));
+ const u32 height = std::min(surface_height, static_cast<u32>(frame_height));
const u32 blk_kind = static_cast<u32>(config.block_linear_kind);
if (blk_kind != 0) {
// swizzle pitch linear to block linear
@@ -169,23 +171,23 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
}
}
-void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
+void Vic::WriteYUVFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config) {
LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame");
const std::size_t surface_width = config.surface_width_minus1 + 1;
const std::size_t surface_height = config.surface_height_minus1 + 1;
const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL;
// Use the minimum of surface/frame dimensions to avoid buffer overflow.
- const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->width));
- const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height));
+ const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->GetWidth()));
+ const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->GetHeight()));
- const auto stride = static_cast<size_t>(frame->linesize[0]);
+ const auto stride = static_cast<size_t>(frame->GetStride(0));
luma_buffer.resize_destructive(aligned_width * surface_height);
chroma_buffer.resize_destructive(aligned_width * surface_height / 2);
// Populate luma buffer
- const u8* luma_src = frame->data[0];
+ const u8* luma_src = frame->GetData(0);
for (std::size_t y = 0; y < frame_height; ++y) {
const std::size_t src = y * stride;
const std::size_t dst = y * aligned_width;
@@ -196,16 +198,16 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
// Chroma
const std::size_t half_height = frame_height / 2;
- const auto half_stride = static_cast<size_t>(frame->linesize[1]);
+ const auto half_stride = static_cast<size_t>(frame->GetStride(1));
- switch (frame->format) {
+ switch (frame->GetPixelFormat()) {
case AV_PIX_FMT_YUV420P: {
// Frame from FFmpeg software
// Populate chroma buffer from both channels with interleaving.
const std::size_t half_width = frame_width / 2;
u8* chroma_buffer_data = chroma_buffer.data();
- const u8* chroma_b_src = frame->data[1];
- const u8* chroma_r_src = frame->data[2];
+ const u8* chroma_b_src = frame->GetData(1);
+ const u8* chroma_r_src = frame->GetData(2);
for (std::size_t y = 0; y < half_height; ++y) {
const std::size_t src = y * half_stride;
const std::size_t dst = y * aligned_width;
@@ -219,7 +221,7 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
case AV_PIX_FMT_NV12: {
// Frame from VA-API hardware
// This is already interleaved so just copy
- const u8* chroma_src = frame->data[1];
+ const u8* chroma_src = frame->GetData(1);
for (std::size_t y = 0; y < half_height; ++y) {
const std::size_t src = y * stride;
const std::size_t dst = y * aligned_width;
diff --git a/src/video_core/host1x/vic.h b/src/video_core/host1x/vic.h
index 3d9753047..6c868f062 100644
--- a/src/video_core/host1x/vic.h
+++ b/src/video_core/host1x/vic.h
@@ -39,9 +39,9 @@ public:
private:
void Execute();
- void WriteRGBFrame(const AVFrame* frame, const VicConfig& config);
+ void WriteRGBFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config);
- void WriteYUVFrame(const AVFrame* frame, const VicConfig& config);
+ void WriteYUVFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config);
Host1x& host1x;
std::shared_ptr<Tegra::Host1x::Nvdec> nvdec_processor;
diff --git a/src/video_core/query_cache/query_cache.h b/src/video_core/query_cache/query_cache.h
index 78b42b518..efa9adf7a 100644
--- a/src/video_core/query_cache/query_cache.h
+++ b/src/video_core/query_cache/query_cache.h
@@ -266,7 +266,7 @@ void QueryCacheBase<Traits>::CounterReport(GPUVAddr addr, QueryType counter_type
return;
}
if (False(query_base->flags & QueryFlagBits::IsFinalValueSynced)) [[unlikely]] {
- UNREACHABLE();
+ ASSERT(false);
return;
}
query_base->value += streamer->GetAmmendValue();
diff --git a/src/video_core/renderer_null/null_rasterizer.cpp b/src/video_core/renderer_null/null_rasterizer.cpp
index 65cd5aa06..4f1d5b548 100644
--- a/src/video_core/renderer_null/null_rasterizer.cpp
+++ b/src/video_core/renderer_null/null_rasterizer.cpp
@@ -3,6 +3,7 @@
#include "common/alignment.h"
#include "core/memory.h"
+#include "video_core/control/channel_state.h"
#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
#include "video_core/renderer_null/null_rasterizer.h"
@@ -99,8 +100,14 @@ bool RasterizerNull::AccelerateDisplay(const Tegra::FramebufferConfig& config,
}
void RasterizerNull::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) {}
-void RasterizerNull::InitializeChannel(Tegra::Control::ChannelState& channel) {}
-void RasterizerNull::BindChannel(Tegra::Control::ChannelState& channel) {}
-void RasterizerNull::ReleaseChannel(s32 channel_id) {}
+void RasterizerNull::InitializeChannel(Tegra::Control::ChannelState& channel) {
+ CreateChannel(channel);
+}
+void RasterizerNull::BindChannel(Tegra::Control::ChannelState& channel) {
+ BindToChannel(channel.bind_id);
+}
+void RasterizerNull::ReleaseChannel(s32 channel_id) {
+ EraseChannel(channel_id);
+}
} // namespace Null
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 38d553d3c..dfd696de6 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -178,13 +178,14 @@ void BufferCacheRuntime::CopyBuffer(GLuint dst_buffer, Buffer& src_buffer,
}
void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, GLuint src_buffer,
- std::span<const VideoCommon::BufferCopy> copies, bool barrier) {
+ std::span<const VideoCommon::BufferCopy> copies, bool barrier,
+ bool) {
CopyBuffer(dst_buffer.Handle(), src_buffer, copies, barrier);
}
void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer,
- std::span<const VideoCommon::BufferCopy> copies) {
- CopyBuffer(dst_buffer.Handle(), src_buffer.Handle(), copies);
+ std::span<const VideoCommon::BufferCopy> copies, bool) {
+ CopyBuffer(dst_buffer.Handle(), src_buffer.Handle(), copies, true);
}
void BufferCacheRuntime::PreCopyBarrier() {
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index e8dbbd3a2..000f29a82 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -30,6 +30,8 @@ public:
void MakeResident(GLenum access) noexcept;
+ void MarkUsage(u64 offset, u64 size) {}
+
[[nodiscard]] GLuint View(u32 offset, u32 size, VideoCore::Surface::PixelFormat format);
[[nodiscard]] GLuint64EXT HostGpuAddr() const noexcept {
@@ -66,22 +68,29 @@ public:
[[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size);
+ bool CanReorderUpload(const Buffer&, std::span<const VideoCommon::BufferCopy>) {
+ return false;
+ }
+
void CopyBuffer(GLuint dst_buffer, GLuint src_buffer,
- std::span<const VideoCommon::BufferCopy> copies, bool barrier = true);
+ std::span<const VideoCommon::BufferCopy> copies, bool barrier);
void CopyBuffer(GLuint dst_buffer, Buffer& src_buffer,
- std::span<const VideoCommon::BufferCopy> copies, bool barrier = true);
+ std::span<const VideoCommon::BufferCopy> copies, bool barrier);
void CopyBuffer(Buffer& dst_buffer, GLuint src_buffer,
- std::span<const VideoCommon::BufferCopy> copies, bool barrier = true);
+ std::span<const VideoCommon::BufferCopy> copies, bool barrier,
+ bool can_reorder_upload = false);
void CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer,
- std::span<const VideoCommon::BufferCopy> copies);
+ std::span<const VideoCommon::BufferCopy> copies, bool);
void PreCopyBarrier();
void PostCopyBarrier();
void Finish();
+ void TickFrame(VideoCommon::SlotVector<Buffer>&) noexcept {}
+
void ClearBuffer(Buffer& dest_buffer, u32 offset, size_t size, u32 value);
void BindIndexBuffer(Buffer& buffer, u32 offset, u32 size);
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 44a771d65..af0a453ee 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -559,7 +559,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
}
void GraphicsPipeline::ConfigureTransformFeedbackImpl() const {
- glTransformFeedbackAttribsNV(num_xfb_attribs, xfb_attribs.data(), GL_SEPARATE_ATTRIBS);
+ const GLenum buffer_mode =
+ num_xfb_buffers_active == 1 ? GL_INTERLEAVED_ATTRIBS : GL_SEPARATE_ATTRIBS;
+ glTransformFeedbackAttribsNV(num_xfb_attribs, xfb_attribs.data(), buffer_mode);
}
void GraphicsPipeline::GenerateTransformFeedbackState() {
@@ -567,12 +569,14 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
// when this is required.
GLint* cursor{xfb_attribs.data()};
+ num_xfb_buffers_active = 0;
for (size_t feedback = 0; feedback < Maxwell::NumTransformFeedbackBuffers; ++feedback) {
const auto& layout = key.xfb_state.layouts[feedback];
UNIMPLEMENTED_IF_MSG(layout.stride != layout.varying_count * 4, "Stride padding");
if (layout.varying_count == 0) {
continue;
}
+ num_xfb_buffers_active++;
const auto& locations = key.xfb_state.varyings[feedback];
std::optional<u32> current_index;
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index 74fc9cc3d..2f70c1ae9 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -154,6 +154,7 @@ private:
static constexpr std::size_t XFB_ENTRY_STRIDE = 3;
GLsizei num_xfb_attribs{};
+ u32 num_xfb_buffers_active{};
std::array<GLint, 128 * XFB_ENTRY_STRIDE * Maxwell::NumTransformFeedbackBuffers> xfb_attribs{};
std::mutex built_mutex;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 27e2de1bf..9995b6dd4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -555,7 +555,7 @@ void RasterizerOpenGL::OnCacheInvalidation(VAddr addr, u64 size) {
}
{
std::scoped_lock lock{buffer_cache.mutex};
- buffer_cache.CachedWriteMemory(addr, size);
+ buffer_cache.WriteMemory(addr, size);
}
shader_cache.InvalidateRegion(addr, size);
}
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 7e7a80740..c4c30d807 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -132,16 +132,12 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
const bool use_accelerated =
rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
const bool is_srgb = use_accelerated && screen_info.is_srgb;
+ RenderScreenshot(*framebuffer, use_accelerated);
- {
- std::scoped_lock lock{rasterizer.LockCaches()};
- RenderScreenshot(*framebuffer, use_accelerated);
-
- Frame* frame = present_manager.GetRenderFrame();
- blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
- scheduler.Flush(*frame->render_ready);
- present_manager.Present(frame);
- }
+ Frame* frame = present_manager.GetRenderFrame();
+ blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
+ scheduler.Flush(*frame->render_ready);
+ present_manager.Present(frame);
gpu.RendererFrameEndNotify();
rasterizer.TickFrame();
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 52fc142d1..66483a900 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -137,6 +137,56 @@ BlitScreen::BlitScreen(Core::Memory::Memory& cpu_memory_, Core::Frontend::EmuWin
BlitScreen::~BlitScreen() = default;
+static Common::Rectangle<f32> NormalizeCrop(const Tegra::FramebufferConfig& framebuffer,
+ const ScreenInfo& screen_info) {
+ f32 left, top, right, bottom;
+
+ if (!framebuffer.crop_rect.IsEmpty()) {
+ // If crop rectangle is not empty, apply properties from rectangle.
+ left = static_cast<f32>(framebuffer.crop_rect.left);
+ top = static_cast<f32>(framebuffer.crop_rect.top);
+ right = static_cast<f32>(framebuffer.crop_rect.right);
+ bottom = static_cast<f32>(framebuffer.crop_rect.bottom);
+ } else {
+ // Otherwise, fall back to framebuffer dimensions.
+ left = 0;
+ top = 0;
+ right = static_cast<f32>(framebuffer.width);
+ bottom = static_cast<f32>(framebuffer.height);
+ }
+
+ // Apply transformation flags.
+ auto framebuffer_transform_flags = framebuffer.transform_flags;
+
+ if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipH)) {
+ // Switch left and right.
+ std::swap(left, right);
+ }
+ if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipV)) {
+ // Switch top and bottom.
+ std::swap(top, bottom);
+ }
+
+ framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipH;
+ framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipV;
+ if (True(framebuffer_transform_flags)) {
+ UNIMPLEMENTED_MSG("Unsupported framebuffer_transform_flags={}",
+ static_cast<u32>(framebuffer_transform_flags));
+ }
+
+ // Get the screen properties.
+ const f32 screen_width = static_cast<f32>(screen_info.width);
+ const f32 screen_height = static_cast<f32>(screen_info.height);
+
+ // Normalize coordinate space.
+ left /= screen_width;
+ top /= screen_height;
+ right /= screen_width;
+ bottom /= screen_height;
+
+ return Common::Rectangle<f32>(left, top, right, bottom);
+}
+
void BlitScreen::Recreate() {
present_manager.WaitPresent();
scheduler.Finish();
@@ -354,17 +404,10 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
source_image_view = smaa->Draw(scheduler, image_index, source_image, source_image_view);
}
if (fsr) {
- auto crop_rect = framebuffer.crop_rect;
- if (crop_rect.GetWidth() == 0) {
- crop_rect.right = framebuffer.width;
- }
- if (crop_rect.GetHeight() == 0) {
- crop_rect.bottom = framebuffer.height;
- }
- crop_rect = crop_rect.Scale(Settings::values.resolution_info.up_factor);
- VkExtent2D fsr_input_size{
- .width = Settings::values.resolution_info.ScaleUp(framebuffer.width),
- .height = Settings::values.resolution_info.ScaleUp(framebuffer.height),
+ const auto crop_rect = NormalizeCrop(framebuffer, screen_info);
+ const VkExtent2D fsr_input_size{
+ .width = Settings::values.resolution_info.ScaleUp(screen_info.width),
+ .height = Settings::values.resolution_info.ScaleUp(screen_info.height),
};
VkImageView fsr_image_view =
fsr->Draw(scheduler, image_index, source_image_view, fsr_input_size, crop_rect);
@@ -1397,61 +1440,37 @@ void BlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayou
void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer,
const Layout::FramebufferLayout layout) const {
- const auto& framebuffer_transform_flags = framebuffer.transform_flags;
- const auto& framebuffer_crop_rect = framebuffer.crop_rect;
-
- static constexpr Common::Rectangle<f32> texcoords{0.f, 0.f, 1.f, 1.f};
- auto left = texcoords.left;
- auto right = texcoords.right;
-
- switch (framebuffer_transform_flags) {
- case Service::android::BufferTransformFlags::Unset:
- break;
- case Service::android::BufferTransformFlags::FlipV:
- // Flip the framebuffer vertically
- left = texcoords.right;
- right = texcoords.left;
- break;
- default:
- UNIMPLEMENTED_MSG("Unsupported framebuffer_transform_flags={}",
- static_cast<u32>(framebuffer_transform_flags));
- break;
- }
+ f32 left, top, right, bottom;
- UNIMPLEMENTED_IF(framebuffer_crop_rect.left != 0);
-
- f32 left_start{};
- if (framebuffer_crop_rect.Top() > 0) {
- left_start = static_cast<f32>(framebuffer_crop_rect.Top()) /
- static_cast<f32>(framebuffer_crop_rect.Bottom());
- }
- f32 scale_u = static_cast<f32>(framebuffer.width) / static_cast<f32>(screen_info.width);
- f32 scale_v = static_cast<f32>(framebuffer.height) / static_cast<f32>(screen_info.height);
- // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering
- // (e.g. handheld mode) on a 1920x1080 framebuffer.
- if (!fsr) {
- if (framebuffer_crop_rect.GetWidth() > 0) {
- scale_u = static_cast<f32>(framebuffer_crop_rect.GetWidth()) /
- static_cast<f32>(screen_info.width);
- }
- if (framebuffer_crop_rect.GetHeight() > 0) {
- scale_v = static_cast<f32>(framebuffer_crop_rect.GetHeight()) /
- static_cast<f32>(screen_info.height);
- }
+ if (fsr) {
+ // FSR has already applied the crop, so we just want to render the image
+ // it has produced.
+ left = 0;
+ top = 0;
+ right = 1;
+ bottom = 1;
+ } else {
+ // Get the normalized crop rectangle.
+ const auto crop = NormalizeCrop(framebuffer, screen_info);
+
+ // Apply the crop.
+ left = crop.left;
+ top = crop.top;
+ right = crop.right;
+ bottom = crop.bottom;
}
+ // Map the coordinates to the screen.
const auto& screen = layout.screen;
const auto x = static_cast<f32>(screen.left);
const auto y = static_cast<f32>(screen.top);
const auto w = static_cast<f32>(screen.GetWidth());
const auto h = static_cast<f32>(screen.GetHeight());
- data.vertices[0] = ScreenRectVertex(x, y, texcoords.top * scale_u, left_start + left * scale_v);
- data.vertices[1] =
- ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left_start + left * scale_v);
- data.vertices[2] =
- ScreenRectVertex(x, y + h, texcoords.top * scale_u, left_start + right * scale_v);
- data.vertices[3] =
- ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, left_start + right * scale_v);
+
+ data.vertices[0] = ScreenRectVertex(x, y, left, top);
+ data.vertices[1] = ScreenRectVertex(x + w, y, right, top);
+ data.vertices[2] = ScreenRectVertex(x, y + h, left, bottom);
+ data.vertices[3] = ScreenRectVertex(x + w, y + h, right, bottom);
}
void BlitScreen::CreateSMAA(VkExtent2D smaa_size) {
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 976c3f6a6..5958f52f7 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -79,13 +79,13 @@ vk::Buffer CreateBuffer(const Device& device, const MemoryAllocator& memory_allo
} // Anonymous namespace
Buffer::Buffer(BufferCacheRuntime&, VideoCommon::NullBufferParams null_params)
- : VideoCommon::BufferBase<VideoCore::RasterizerInterface>(null_params) {}
+ : VideoCommon::BufferBase<VideoCore::RasterizerInterface>(null_params), tracker{4096} {}
Buffer::Buffer(BufferCacheRuntime& runtime, VideoCore::RasterizerInterface& rasterizer_,
VAddr cpu_addr_, u64 size_bytes_)
: VideoCommon::BufferBase<VideoCore::RasterizerInterface>(rasterizer_, cpu_addr_, size_bytes_),
- device{&runtime.device}, buffer{
- CreateBuffer(*device, runtime.memory_allocator, SizeBytes())} {
+ device{&runtime.device}, buffer{CreateBuffer(*device, runtime.memory_allocator, SizeBytes())},
+ tracker{SizeBytes()} {
if (runtime.device.HasDebuggingToolAttached()) {
buffer.SetObjectNameEXT(fmt::format("Buffer 0x{:x}", CpuAddr()).c_str());
}
@@ -359,12 +359,31 @@ u32 BufferCacheRuntime::GetStorageBufferAlignment() const {
return static_cast<u32>(device.GetStorageBufferAlignment());
}
+void BufferCacheRuntime::TickFrame(VideoCommon::SlotVector<Buffer>& slot_buffers) noexcept {
+ for (auto it = slot_buffers.begin(); it != slot_buffers.end(); it++) {
+ it->ResetUsageTracking();
+ }
+}
+
void BufferCacheRuntime::Finish() {
scheduler.Finish();
}
+bool BufferCacheRuntime::CanReorderUpload(const Buffer& buffer,
+ std::span<const VideoCommon::BufferCopy> copies) {
+ if (Settings::values.disable_buffer_reorder) {
+ return false;
+ }
+ const bool can_use_upload_cmdbuf =
+ std::ranges::all_of(copies, [&](const VideoCommon::BufferCopy& copy) {
+ return !buffer.IsRegionUsed(copy.dst_offset, copy.size);
+ });
+ return can_use_upload_cmdbuf;
+}
+
void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
- std::span<const VideoCommon::BufferCopy> copies, bool barrier) {
+ std::span<const VideoCommon::BufferCopy> copies, bool barrier,
+ bool can_reorder_upload) {
if (dst_buffer == VK_NULL_HANDLE || src_buffer == VK_NULL_HANDLE) {
return;
}
@@ -380,9 +399,18 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
};
+
// Measuring a popular game, this number never exceeds the specified size once data is warmed up
boost::container::small_vector<VkBufferCopy, 8> vk_copies(copies.size());
std::ranges::transform(copies, vk_copies.begin(), MakeBufferCopy);
+ if (src_buffer == staging_pool.StreamBuf() && can_reorder_upload) {
+ scheduler.RecordWithUploadBuffer([src_buffer, dst_buffer, vk_copies](
+ vk::CommandBuffer, vk::CommandBuffer upload_cmdbuf) {
+ upload_cmdbuf.CopyBuffer(src_buffer, dst_buffer, vk_copies);
+ });
+ return;
+ }
+
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) {
if (barrier) {
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index 833dfac45..0b3fbd6d0 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -5,6 +5,7 @@
#include "video_core/buffer_cache/buffer_cache_base.h"
#include "video_core/buffer_cache/memory_tracker_base.h"
+#include "video_core/buffer_cache/usage_tracker.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/renderer_vulkan/vk_compute_pass.h"
#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
@@ -34,6 +35,18 @@ public:
return *buffer;
}
+ [[nodiscard]] bool IsRegionUsed(u64 offset, u64 size) const noexcept {
+ return tracker.IsUsed(offset, size);
+ }
+
+ void MarkUsage(u64 offset, u64 size) noexcept {
+ tracker.Track(offset, size);
+ }
+
+ void ResetUsageTracking() noexcept {
+ tracker.Reset();
+ }
+
operator VkBuffer() const noexcept {
return *buffer;
}
@@ -49,6 +62,7 @@ private:
const Device* device{};
vk::Buffer buffer;
std::vector<BufferView> views;
+ VideoCommon::UsageTracker tracker;
};
class QuadArrayIndexBuffer;
@@ -67,6 +81,8 @@ public:
ComputePassDescriptorQueue& compute_pass_descriptor_queue,
DescriptorPool& descriptor_pool);
+ void TickFrame(VideoCommon::SlotVector<Buffer>& slot_buffers) noexcept;
+
void Finish();
u64 GetDeviceLocalMemory() const;
@@ -81,12 +97,15 @@ public:
[[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size, bool deferred = false);
+ bool CanReorderUpload(const Buffer& buffer, std::span<const VideoCommon::BufferCopy> copies);
+
void FreeDeferredStagingBuffer(StagingBufferRef& ref);
void PreCopyBarrier();
void CopyBuffer(VkBuffer src_buffer, VkBuffer dst_buffer,
- std::span<const VideoCommon::BufferCopy> copies, bool barrier = true);
+ std::span<const VideoCommon::BufferCopy> copies, bool barrier,
+ bool can_reorder_upload = false);
void PostCopyBarrier();
diff --git a/src/video_core/renderer_vulkan/vk_fsr.cpp b/src/video_core/renderer_vulkan/vk_fsr.cpp
index ce8f3f3c2..f7a05fbc0 100644
--- a/src/video_core/renderer_vulkan/vk_fsr.cpp
+++ b/src/video_core/renderer_vulkan/vk_fsr.cpp
@@ -34,7 +34,7 @@ FSR::FSR(const Device& device_, MemoryAllocator& memory_allocator_, size_t image
}
VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view,
- VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect) {
+ VkExtent2D input_image_extent, const Common::Rectangle<f32>& crop_rect) {
UpdateDescriptorSet(image_index, image_view);
@@ -61,15 +61,21 @@ VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImageView imag
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *easu_pipeline);
+ const f32 input_image_width = static_cast<f32>(input_image_extent.width);
+ const f32 input_image_height = static_cast<f32>(input_image_extent.height);
+ const f32 output_image_width = static_cast<f32>(output_size.width);
+ const f32 output_image_height = static_cast<f32>(output_size.height);
+ const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_image_width;
+ const f32 viewport_x = crop_rect.left * input_image_width;
+ const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_image_height;
+ const f32 viewport_y = crop_rect.top * input_image_height;
+
std::array<u32, 4 * 4> push_constants;
- FsrEasuConOffset(
- push_constants.data() + 0, push_constants.data() + 4, push_constants.data() + 8,
- push_constants.data() + 12,
-
- static_cast<f32>(crop_rect.GetWidth()), static_cast<f32>(crop_rect.GetHeight()),
- static_cast<f32>(input_image_extent.width), static_cast<f32>(input_image_extent.height),
- static_cast<f32>(output_size.width), static_cast<f32>(output_size.height),
- static_cast<f32>(crop_rect.left), static_cast<f32>(crop_rect.top));
+ FsrEasuConOffset(push_constants.data() + 0, push_constants.data() + 4,
+ push_constants.data() + 8, push_constants.data() + 12,
+
+ viewport_width, viewport_height, input_image_width, input_image_height,
+ output_image_width, output_image_height, viewport_x, viewport_y);
cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, push_constants);
{
diff --git a/src/video_core/renderer_vulkan/vk_fsr.h b/src/video_core/renderer_vulkan/vk_fsr.h
index 8bb9fc23a..3505c1416 100644
--- a/src/video_core/renderer_vulkan/vk_fsr.h
+++ b/src/video_core/renderer_vulkan/vk_fsr.h
@@ -17,7 +17,7 @@ public:
explicit FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count,
VkExtent2D output_size);
VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view,
- VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect);
+ VkExtent2D input_image_extent, const Common::Rectangle<f32>& crop_rect);
private:
void CreateDescriptorPool();
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
index 6b288b994..ac8b6e838 100644
--- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
+++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp
@@ -100,12 +100,14 @@ void MasterSemaphore::Wait(u64 tick) {
Refresh();
}
-VkResult MasterSemaphore::SubmitQueue(vk::CommandBuffer& cmdbuf, VkSemaphore signal_semaphore,
- VkSemaphore wait_semaphore, u64 host_tick) {
+VkResult MasterSemaphore::SubmitQueue(vk::CommandBuffer& cmdbuf, vk::CommandBuffer& upload_cmdbuf,
+ VkSemaphore signal_semaphore, VkSemaphore wait_semaphore,
+ u64 host_tick) {
if (semaphore) {
- return SubmitQueueTimeline(cmdbuf, signal_semaphore, wait_semaphore, host_tick);
+ return SubmitQueueTimeline(cmdbuf, upload_cmdbuf, signal_semaphore, wait_semaphore,
+ host_tick);
} else {
- return SubmitQueueFence(cmdbuf, signal_semaphore, wait_semaphore, host_tick);
+ return SubmitQueueFence(cmdbuf, upload_cmdbuf, signal_semaphore, wait_semaphore, host_tick);
}
}
@@ -115,6 +117,7 @@ static constexpr std::array<VkPipelineStageFlags, 2> wait_stage_masks{
};
VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf,
+ vk::CommandBuffer& upload_cmdbuf,
VkSemaphore signal_semaphore,
VkSemaphore wait_semaphore, u64 host_tick) {
const VkSemaphore timeline_semaphore = *semaphore;
@@ -123,6 +126,8 @@ VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf,
const std::array signal_values{host_tick, u64(0)};
const std::array signal_semaphores{timeline_semaphore, signal_semaphore};
+ const std::array cmdbuffers{*upload_cmdbuf, *cmdbuf};
+
const u32 num_wait_semaphores = wait_semaphore ? 1 : 0;
const VkTimelineSemaphoreSubmitInfo timeline_si{
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
@@ -138,8 +143,8 @@ VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf,
.waitSemaphoreCount = num_wait_semaphores,
.pWaitSemaphores = &wait_semaphore,
.pWaitDstStageMask = wait_stage_masks.data(),
- .commandBufferCount = 1,
- .pCommandBuffers = cmdbuf.address(),
+ .commandBufferCount = static_cast<u32>(cmdbuffers.size()),
+ .pCommandBuffers = cmdbuffers.data(),
.signalSemaphoreCount = num_signal_semaphores,
.pSignalSemaphores = signal_semaphores.data(),
};
@@ -147,19 +152,23 @@ VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf,
return device.GetGraphicsQueue().Submit(submit_info);
}
-VkResult MasterSemaphore::SubmitQueueFence(vk::CommandBuffer& cmdbuf, VkSemaphore signal_semaphore,
- VkSemaphore wait_semaphore, u64 host_tick) {
+VkResult MasterSemaphore::SubmitQueueFence(vk::CommandBuffer& cmdbuf,
+ vk::CommandBuffer& upload_cmdbuf,
+ VkSemaphore signal_semaphore, VkSemaphore wait_semaphore,
+ u64 host_tick) {
const u32 num_signal_semaphores = signal_semaphore ? 1 : 0;
const u32 num_wait_semaphores = wait_semaphore ? 1 : 0;
+ const std::array cmdbuffers{*upload_cmdbuf, *cmdbuf};
+
const VkSubmitInfo submit_info{
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr,
.waitSemaphoreCount = num_wait_semaphores,
.pWaitSemaphores = &wait_semaphore,
.pWaitDstStageMask = wait_stage_masks.data(),
- .commandBufferCount = 1,
- .pCommandBuffers = cmdbuf.address(),
+ .commandBufferCount = static_cast<u32>(cmdbuffers.size()),
+ .pCommandBuffers = cmdbuffers.data(),
.signalSemaphoreCount = num_signal_semaphores,
.pSignalSemaphores = &signal_semaphore,
};
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.h b/src/video_core/renderer_vulkan/vk_master_semaphore.h
index 3f599d7bd..7dfb93ffb 100644
--- a/src/video_core/renderer_vulkan/vk_master_semaphore.h
+++ b/src/video_core/renderer_vulkan/vk_master_semaphore.h
@@ -52,14 +52,16 @@ public:
void Wait(u64 tick);
/// Submits the device graphics queue, updating the tick as necessary
- VkResult SubmitQueue(vk::CommandBuffer& cmdbuf, VkSemaphore signal_semaphore,
- VkSemaphore wait_semaphore, u64 host_tick);
+ VkResult SubmitQueue(vk::CommandBuffer& cmdbuf, vk::CommandBuffer& upload_cmdbuf,
+ VkSemaphore signal_semaphore, VkSemaphore wait_semaphore, u64 host_tick);
private:
- VkResult SubmitQueueTimeline(vk::CommandBuffer& cmdbuf, VkSemaphore signal_semaphore,
- VkSemaphore wait_semaphore, u64 host_tick);
- VkResult SubmitQueueFence(vk::CommandBuffer& cmdbuf, VkSemaphore signal_semaphore,
- VkSemaphore wait_semaphore, u64 host_tick);
+ VkResult SubmitQueueTimeline(vk::CommandBuffer& cmdbuf, vk::CommandBuffer& upload_cmdbuf,
+ VkSemaphore signal_semaphore, VkSemaphore wait_semaphore,
+ u64 host_tick);
+ VkResult SubmitQueueFence(vk::CommandBuffer& cmdbuf, vk::CommandBuffer& upload_cmdbuf,
+ VkSemaphore signal_semaphore, VkSemaphore wait_semaphore,
+ u64 host_tick);
void WaitThread(std::stop_token token);
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 0d604eee3..2a13b2a72 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -263,6 +263,22 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
info.y_negate = key.state.y_negate != 0;
return info;
}
+
+size_t GetTotalPipelineWorkers() {
+ const size_t max_core_threads =
+ std::max<size_t>(static_cast<size_t>(std::thread::hardware_concurrency()), 2ULL) - 1ULL;
+#ifdef ANDROID
+ // Leave at least a few cores free in android
+ constexpr size_t free_cores = 3ULL;
+ if (max_core_threads <= free_cores) {
+ return 1ULL;
+ }
+ return max_core_threads - free_cores;
+#else
+ return max_core_threads;
+#endif
+}
+
} // Anonymous namespace
size_t ComputePipelineCacheKey::Hash() const noexcept {
@@ -294,11 +310,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
texture_cache{texture_cache_}, shader_notify{shader_notify_},
use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()},
use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()},
-#ifdef ANDROID
- workers(1, "VkPipelineBuilder"),
-#else
- workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"),
-#endif
+ workers(device.HasBrokenParallelShaderCompiling() ? 1ULL : GetTotalPipelineWorkers(),
+ "VkPipelineBuilder"),
serialization_thread(1, "VkPipelineSerialization") {
const auto& float_control{device.FloatControlProperties()};
const VkDriverId driver_id{device.GetDriverID()};
@@ -338,6 +351,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
.support_native_ndc = device.IsExtDepthClipControlSupported(),
.support_scaled_attributes = !device.MustEmulateScaledFormats(),
+ .support_multi_viewport = device.SupportsMultiViewport(),
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp
index 66c03bf17..078777cdd 100644
--- a/src/video_core/renderer_vulkan/vk_query_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp
@@ -211,6 +211,13 @@ public:
return;
}
PauseCounter();
+ const auto driver_id = device.GetDriverID();
+ if (driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
+ driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
+ pending_sync.clear();
+ sync_values_stash.clear();
+ return;
+ }
sync_values_stash.clear();
sync_values_stash.emplace_back();
std::vector<HostSyncValues>* sync_values = &sync_values_stash.back();
@@ -1378,6 +1385,12 @@ bool QueryCacheRuntime::HostConditionalRenderingCompareValues(VideoCommon::Looku
return true;
}
+ auto driver_id = impl->device.GetDriverID();
+ if (driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
+ driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
+ return true;
+ }
+
for (size_t i = 0; i < 2; i++) {
is_null[i] = !is_in_ac[i] && check_value(objects[i]->address);
}
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 059b7cb40..e0ab1eaac 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -82,7 +82,7 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in
}
if (y_negate) {
- y += height;
+ y += conv(static_cast<f32>(regs.surface_clip.height));
height = -height;
}
@@ -199,7 +199,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
if (!pipeline) {
return;
}
- std::scoped_lock lock{LockCaches()};
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
// update engine as channel may be different.
pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed);
@@ -621,7 +621,7 @@ void RasterizerVulkan::OnCacheInvalidation(VAddr addr, u64 size) {
}
{
std::scoped_lock lock{buffer_cache.mutex};
- buffer_cache.CachedWriteMemory(addr, size);
+ buffer_cache.WriteMemory(addr, size);
}
pipeline_cache.InvalidateRegion(addr, size);
}
@@ -710,7 +710,6 @@ void RasterizerVulkan::TiledCacheBarrier() {
}
void RasterizerVulkan::FlushCommands() {
- std::scoped_lock lock{LockCaches()};
if (draw_counter == 0) {
return;
}
@@ -808,7 +807,6 @@ void RasterizerVulkan::FlushWork() {
if ((++draw_counter & 7) != 7) {
return;
}
- std::scoped_lock lock{LockCaches()};
if (draw_counter < DRAWS_TO_DISPATCH) {
// Send recorded tasks to the worker thread
scheduler.DispatchWork();
@@ -923,9 +921,13 @@ void RasterizerVulkan::UpdateDynamicStates() {
}
void RasterizerVulkan::HandleTransformFeedback() {
+ static std::once_flag warn_unsupported;
+
const auto& regs = maxwell3d->regs;
if (!device.IsExtTransformFeedbackSupported()) {
- LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported");
+ std::call_once(warn_unsupported, [&] {
+ LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported");
+ });
return;
}
query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount,
@@ -1503,7 +1505,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
CreateChannel(channel);
{
- std::scoped_lock lock{LockCaches()};
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.CreateChannel(channel);
buffer_cache.CreateChannel(channel);
}
@@ -1516,7 +1518,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
const s32 channel_id = channel.bind_id;
BindToChannel(channel_id);
{
- std::scoped_lock lock{LockCaches()};
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.BindToChannel(channel_id);
buffer_cache.BindToChannel(channel_id);
}
@@ -1529,7 +1531,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
EraseChannel(channel_id);
{
- std::scoped_lock lock{LockCaches()};
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.EraseChannel(channel_id);
buffer_cache.EraseChannel(channel_id);
}
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index ce3dfbaab..ad069556c 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -133,10 +133,6 @@ public:
void ReleaseChannel(s32 channel_id) override;
- std::scoped_lock<std::recursive_mutex, std::recursive_mutex> LockCaches() {
- return std::scoped_lock{buffer_cache.mutex, texture_cache.mutex};
- }
-
private:
static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48;
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp
index 3be7837f4..146923db4 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.cpp
+++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp
@@ -22,11 +22,12 @@ namespace Vulkan {
MICROPROFILE_DECLARE(Vulkan_WaitForWorker);
-void Scheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf) {
+void Scheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf,
+ vk::CommandBuffer upload_cmdbuf) {
auto command = first;
while (command != nullptr) {
auto next = command->GetNext();
- command->Execute(cmdbuf);
+ command->Execute(cmdbuf, upload_cmdbuf);
command->~Command();
command = next;
}
@@ -180,7 +181,7 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
// Perform the work, tracking whether the chunk was a submission
// before executing.
const bool has_submit = work->HasSubmit();
- work->ExecuteAll(current_cmdbuf);
+ work->ExecuteAll(current_cmdbuf, current_upload_cmdbuf);
// If the chunk was a submission, reallocate the command buffer.
if (has_submit) {
@@ -205,6 +206,13 @@ void Scheduler::AllocateWorkerCommandBuffer() {
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
.pInheritanceInfo = nullptr,
});
+ current_upload_cmdbuf = vk::CommandBuffer(command_pool->Commit(), device.GetDispatchLoader());
+ current_upload_cmdbuf.Begin({
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+ .pNext = nullptr,
+ .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
+ .pInheritanceInfo = nullptr,
+ });
}
u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) {
@@ -212,7 +220,17 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
InvalidateState();
const u64 signal_value = master_semaphore->NextTick();
- Record([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf) {
+ RecordWithUploadBuffer([signal_semaphore, wait_semaphore, signal_value,
+ this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) {
+ static constexpr VkMemoryBarrier WRITE_BARRIER{
+ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+ .pNext = nullptr,
+ .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
+ .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
+ };
+ upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER);
+ upload_cmdbuf.End();
cmdbuf.End();
if (on_submit) {
@@ -221,7 +239,7 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
std::scoped_lock lock{submit_mutex};
switch (const VkResult result = master_semaphore->SubmitQueue(
- cmdbuf, signal_semaphore, wait_semaphore, signal_value)) {
+ cmdbuf, upload_cmdbuf, signal_semaphore, wait_semaphore, signal_value)) {
case VK_SUCCESS:
break;
case VK_ERROR_DEVICE_LOST:
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h
index da03803aa..f8d8ca80a 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.h
+++ b/src/video_core/renderer_vulkan/vk_scheduler.h
@@ -80,7 +80,8 @@ public:
/// Send work to a separate thread.
template <typename T>
- void Record(T&& command) {
+ requires std::is_invocable_v<T, vk::CommandBuffer, vk::CommandBuffer>
+ void RecordWithUploadBuffer(T&& command) {
if (chunk->Record(command)) {
return;
}
@@ -88,6 +89,15 @@ public:
(void)chunk->Record(command);
}
+ template <typename T>
+ requires std::is_invocable_v<T, vk::CommandBuffer>
+ void Record(T&& c) {
+ this->RecordWithUploadBuffer(
+ [command = std::move(c)](vk::CommandBuffer cmdbuf, vk::CommandBuffer) {
+ command(cmdbuf);
+ });
+ }
+
/// Returns the current command buffer tick.
[[nodiscard]] u64 CurrentTick() const noexcept {
return master_semaphore->CurrentTick();
@@ -119,7 +129,7 @@ private:
public:
virtual ~Command() = default;
- virtual void Execute(vk::CommandBuffer cmdbuf) const = 0;
+ virtual void Execute(vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) const = 0;
Command* GetNext() const {
return next;
@@ -142,8 +152,8 @@ private:
TypedCommand(TypedCommand&&) = delete;
TypedCommand& operator=(TypedCommand&&) = delete;
- void Execute(vk::CommandBuffer cmdbuf) const override {
- command(cmdbuf);
+ void Execute(vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) const override {
+ command(cmdbuf, upload_cmdbuf);
}
private:
@@ -152,7 +162,7 @@ private:
class CommandChunk final {
public:
- void ExecuteAll(vk::CommandBuffer cmdbuf);
+ void ExecuteAll(vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf);
template <typename T>
bool Record(T& command) {
@@ -228,6 +238,7 @@ private:
VideoCommon::QueryCacheBase<QueryCacheParams>* query_cache = nullptr;
vk::CommandBuffer current_cmdbuf;
+ vk::CommandBuffer current_upload_cmdbuf;
std::unique_ptr<CommandChunk> chunk;
std::function<void()> on_submit;
diff --git a/src/video_core/renderer_vulkan/vk_smaa.cpp b/src/video_core/renderer_vulkan/vk_smaa.cpp
index 5efd7d66e..70644ea82 100644
--- a/src/video_core/renderer_vulkan/vk_smaa.cpp
+++ b/src/video_core/renderer_vulkan/vk_smaa.cpp
@@ -672,7 +672,7 @@ void SMAA::UploadImages(Scheduler& scheduler) {
UploadImage(m_device, m_allocator, scheduler, m_static_images[Search], search_extent,
VK_FORMAT_R8_UNORM, ARRAY_TO_SPAN(searchTexBytes));
- scheduler.Record([&](vk::CommandBuffer& cmdbuf) {
+ scheduler.Record([&](vk::CommandBuffer cmdbuf) {
for (auto& images : m_dynamic_images) {
for (size_t i = 0; i < MaxDynamicImage; i++) {
ClearColorImage(cmdbuf, *images.images[i]);
@@ -707,7 +707,7 @@ VkImageView SMAA::Draw(Scheduler& scheduler, size_t image_index, VkImage source_
UpdateDescriptorSets(source_image_view, image_index);
scheduler.RequestOutsideRenderPassOperationContext();
- scheduler.Record([=, this](vk::CommandBuffer& cmdbuf) {
+ scheduler.Record([=, this](vk::CommandBuffer cmdbuf) {
TransitionImageLayout(cmdbuf, source_image, VK_IMAGE_LAYOUT_GENERAL);
TransitionImageLayout(cmdbuf, edges_image, VK_IMAGE_LAYOUT_GENERAL);
BeginRenderPass(cmdbuf, m_renderpasses[EdgeDetection], edge_detection_framebuffer,
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
index d3deb9072..f63a20327 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
@@ -36,6 +36,10 @@ public:
StagingBufferRef Request(size_t size, MemoryUsage usage, bool deferred = false);
void FreeDeferred(StagingBufferRef& ref);
+ [[nodiscard]] VkBuffer StreamBuf() const noexcept {
+ return *stream_buffer;
+ }
+
void TickFrame();
private:
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index de34f6d49..5dbec2e62 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1785,8 +1785,22 @@ ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo& info,
: VideoCommon::ImageViewBase{info, view_info, gpu_addr_},
buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {}
-ImageView::ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams& params)
- : VideoCommon::ImageViewBase{params} {}
+ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params)
+ : VideoCommon::ImageViewBase{params}, device{&runtime.device} {
+ if (device->HasNullDescriptor()) {
+ return;
+ }
+
+ // Handle fallback for devices without nullDescriptor
+ ImageInfo info{};
+ info.format = PixelFormat::A8B8G8R8_UNORM;
+
+ null_image = MakeImage(*device, runtime.memory_allocator, info, {});
+ image_handle = *null_image;
+ for (u32 i = 0; i < Shader::NUM_TEXTURE_TYPES; i++) {
+ image_views[i] = MakeView(VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_ASPECT_COLOR_BIT);
+ }
+}
ImageView::~ImageView() = default;
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 7a0807709..edf5d7635 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -267,6 +267,7 @@ private:
vk::ImageView depth_view;
vk::ImageView stencil_view;
vk::ImageView color_view;
+ vk::Image null_image;
VkImage image_handle = VK_NULL_HANDLE;
VkImageView render_target = VK_NULL_HANDLE;
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
diff --git a/src/video_core/texture_cache/slot_vector.h b/src/video_core/texture_cache/slot_vector.h
index 9df6a2903..3ffa2a661 100644
--- a/src/video_core/texture_cache/slot_vector.h
+++ b/src/video_core/texture_cache/slot_vector.h
@@ -138,6 +138,10 @@ public:
return Iterator(this, SlotId{SlotId::INVALID_INDEX});
}
+ [[nodiscard]] size_t size() const noexcept {
+ return values_capacity - free_list.size();
+ }
+
private:
struct NonTrivialDummy {
NonTrivialDummy() noexcept {}
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index e518756d2..fde36a49c 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -635,6 +635,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
has_broken_cube_compatibility = true;
}
}
+ if (is_qualcomm) {
+ const u32 version = (properties.properties.driverVersion << 3) >> 3;
+ if (version < VK_MAKE_API_VERSION(0, 255, 615, 512)) {
+ has_broken_parallel_compiling = true;
+ }
+ }
if (extensions.sampler_filter_minmax && is_amd) {
// Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken.
if (!features.shader_float16_int8.shaderFloat16) {
@@ -863,7 +869,8 @@ bool Device::ShouldBoostClocks() const {
driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA ||
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP;
- const bool is_steam_deck = vendor_id == 0x1002 && device_id == 0x163F;
+ const bool is_steam_deck = (vendor_id == 0x1002 && device_id == 0x163F) ||
+ (vendor_id == 0x1002 && device_id == 0x1435);
const bool is_debugging = this->HasDebuggingToolAttached();
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index b213ed7dd..4f3846345 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -102,6 +102,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
+ EXTENSION_NAME(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
@@ -599,6 +600,11 @@ public:
return has_broken_cube_compatibility;
}
+ /// Returns true if parallel shader compiling has issues with the current driver.
+ bool HasBrokenParallelShaderCompiling() const {
+ return has_broken_parallel_compiling;
+ }
+
/// Returns the vendor name reported from Vulkan.
std::string_view GetVendorName() const {
return properties.driver.driverName;
@@ -663,6 +669,10 @@ public:
return supports_conditional_barriers;
}
+ bool SupportsMultiViewport() const {
+ return features2.features.multiViewport;
+ }
+
[[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id,
u32 driver_version) {
if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {
@@ -794,6 +804,7 @@ private:
bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device.
bool has_broken_compute{}; ///< Compute shaders can cause crashes
bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit
+ bool has_broken_parallel_compiling{}; ///< Has broken parallel shader compiling.
bool has_renderdoc{}; ///< Has RenderDoc attached
bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
bool supports_d24_depth{}; ///< Supports D24 depth buffers.
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 0487cd3b6..a0c70797f 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -1101,6 +1101,10 @@ public:
return &handle;
}
+ VkCommandBuffer operator*() const noexcept {
+ return handle;
+ }
+
void Begin(const VkCommandBufferBeginInfo& begin_info) const {
Check(dld->vkBeginCommandBuffer(handle, &begin_info));
}
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 33e1fb663..90278052a 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -38,8 +38,6 @@ add_executable(yuzu
compatdb.ui
compatibility_list.cpp
compatibility_list.h
- configuration/config.cpp
- configuration/config.h
configuration/configuration_shared.cpp
configuration/configuration_shared.h
configuration/configure.ui
@@ -147,6 +145,8 @@ add_executable(yuzu
configuration/shared_translation.h
configuration/shared_widget.cpp
configuration/shared_widget.h
+ configuration/qt_config.cpp
+ configuration/qt_config.h
debugger/console.cpp
debugger/console.h
debugger/controller.cpp
@@ -252,6 +252,7 @@ file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*)
if (ENABLE_QT_TRANSLATION)
set(YUZU_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend")
option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF)
+ option(WORKAROUND_BROKEN_LUPDATE "Run lupdate directly through CMake if Qt's convenience wrappers don't work" OFF)
# Update source TS file if enabled
if (GENERATE_QT_TRANSLATION)
@@ -259,19 +260,51 @@ if (ENABLE_QT_TRANSLATION)
# these calls to qt_create_translation also creates a rule to generate en.qm which conflicts with providing english plurals
# so we have to set a OUTPUT_LOCATION so that we don't have multiple rules to generate en.qm
set_source_files_properties(${YUZU_QT_LANGUAGES}/en.ts PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations")
- qt_create_translation(QM_FILES
- ${SRCS}
- ${UIS}
- ${YUZU_QT_LANGUAGES}/en.ts
- OPTIONS
- -source-language en_US
- -target-language en_US
- )
+ if (WORKAROUND_BROKEN_LUPDATE)
+ add_custom_command(OUTPUT ${YUZU_QT_LANGUAGES}/en.ts
+ COMMAND lupdate
+ -source-language en_US
+ -target-language en_US
+ ${SRCS}
+ ${UIS}
+ -ts ${YUZU_QT_LANGUAGES}/en.ts
+ DEPENDS
+ ${SRCS}
+ ${UIS}
+ WORKING_DIRECTORY
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+ else()
+ qt_create_translation(QM_FILES
+ ${SRCS}
+ ${UIS}
+ ${YUZU_QT_LANGUAGES}/en.ts
+ OPTIONS
+ -source-language en_US
+ -target-language en_US
+ )
+ endif()
# Generate plurals into dist/english_plurals/generated_en.ts so it can be used to revise dist/english_plurals/en.ts
set(GENERATED_PLURALS_FILE ${PROJECT_SOURCE_DIR}/dist/english_plurals/generated_en.ts)
set_source_files_properties(${GENERATED_PLURALS_FILE} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/plurals")
- qt_create_translation(QM_FILES ${SRCS} ${UIS} ${GENERATED_PLURALS_FILE} OPTIONS -pluralonly -source-language en_US -target-language en_US)
+ if (WORKAROUND_BROKEN_LUPDATE)
+ add_custom_command(OUTPUT ${GENERATED_PLURALS_FILE}
+ COMMAND lupdate
+ -source-language en_US
+ -target-language en_US
+ ${SRCS}
+ ${UIS}
+ -ts ${GENERATED_PLURALS_FILE}
+ DEPENDS
+ ${SRCS}
+ ${UIS}
+ WORKING_DIRECTORY
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+ else()
+ qt_create_translation(QM_FILES ${SRCS} ${UIS} ${GENERATED_PLURALS_FILE} OPTIONS -pluralonly -source-language en_US -target-language en_US)
+ endif()
add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts ${GENERATED_PLURALS_FILE})
endif()
@@ -344,7 +377,7 @@ endif()
create_target_directory_groups(yuzu)
-target_link_libraries(yuzu PRIVATE common core input_common network video_core)
+target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core)
target_link_libraries(yuzu PRIVATE Boost::headers glad Qt${QT_MAJOR_VERSION}::Widgets)
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index 515cb7ce6..9e5319716 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -13,7 +13,6 @@
#include "core/hid/hid_core.h"
#include "core/hid/hid_types.h"
#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/hid.h"
#include "core/hle/service/sm/sm.h"
#include "ui_qt_controller.h"
#include "yuzu/applets/qt_controller.h"
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
deleted file mode 100644
index baa3e55f3..000000000
--- a/src/yuzu/configuration/config.cpp
+++ /dev/null
@@ -1,1306 +0,0 @@
-// SPDX-FileCopyrightText: 2014 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <algorithm>
-#include <array>
-#include <QKeySequence>
-#include <QSettings>
-#include "common/fs/fs.h"
-#include "common/fs/path_util.h"
-#include "common/settings.h"
-#include "common/settings_common.h"
-#include "common/settings_enums.h"
-#include "core/core.h"
-#include "core/hle/service/acc/profile_manager.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "input_common/main.h"
-#include "network/network.h"
-#include "yuzu/configuration/config.h"
-
-namespace FS = Common::FS;
-
-Config::Config(const std::string& config_name, ConfigType config_type)
- : type(config_type), global{config_type == ConfigType::GlobalConfig} {
- Initialize(config_name);
-}
-
-Config::~Config() {
- if (global) {
- Save();
- }
-}
-
-const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = {
- Qt::Key_C, Qt::Key_X, Qt::Key_V, Qt::Key_Z, Qt::Key_F,
- Qt::Key_G, Qt::Key_Q, Qt::Key_E, Qt::Key_R, Qt::Key_T,
- Qt::Key_M, Qt::Key_N, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right,
- Qt::Key_Down, Qt::Key_Q, Qt::Key_E, 0, 0,
-};
-
-const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motions = {
- Qt::Key_7,
- Qt::Key_8,
-};
-
-const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{
- {
- Qt::Key_W,
- Qt::Key_S,
- Qt::Key_A,
- Qt::Key_D,
- },
- {
- Qt::Key_I,
- Qt::Key_K,
- Qt::Key_J,
- Qt::Key_L,
- },
-}};
-
-const std::array<int, 2> Config::default_stick_mod = {
- Qt::Key_Shift,
- 0,
-};
-
-const std::array<int, 2> Config::default_ringcon_analogs{{
- Qt::Key_A,
- Qt::Key_D,
-}};
-
-const std::map<Settings::AntiAliasing, QString> Config::anti_aliasing_texts_map = {
- {Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "None"))},
- {Settings::AntiAliasing::Fxaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FXAA"))},
- {Settings::AntiAliasing::Smaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SMAA"))},
-};
-
-const std::map<Settings::ScalingFilter, QString> Config::scaling_filter_texts_map = {
- {Settings::ScalingFilter::NearestNeighbor,
- QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Nearest"))},
- {Settings::ScalingFilter::Bilinear,
- QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
- {Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
- {Settings::ScalingFilter::Gaussian,
- QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
- {Settings::ScalingFilter::ScaleForce,
- QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
- {Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
-};
-
-const std::map<Settings::ConsoleMode, QString> Config::use_docked_mode_texts_map = {
- {Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))},
- {Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))},
-};
-
-const std::map<Settings::GpuAccuracy, QString> Config::gpu_accuracy_texts_map = {
- {Settings::GpuAccuracy::Normal, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Normal"))},
- {Settings::GpuAccuracy::High, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "High"))},
- {Settings::GpuAccuracy::Extreme, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Extreme"))},
-};
-
-const std::map<Settings::RendererBackend, QString> Config::renderer_backend_texts_map = {
- {Settings::RendererBackend::Vulkan, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Vulkan"))},
- {Settings::RendererBackend::OpenGL, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "OpenGL"))},
- {Settings::RendererBackend::Null, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Null"))},
-};
-
-const std::map<Settings::ShaderBackend, QString> Config::shader_backend_texts_map = {
- {Settings::ShaderBackend::Glsl, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLSL"))},
- {Settings::ShaderBackend::Glasm, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLASM"))},
- {Settings::ShaderBackend::SpirV, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SPIRV"))},
-};
-
-// This shouldn't have anything except static initializers (no functions). So
-// QKeySequence(...).toString() is NOT ALLOWED HERE.
-// This must be in alphabetical order according to action name as it must have the same order as
-// UISetting::values.shortcuts, which is alphabetically ordered.
-// clang-format off
-const std::array<UISettings::Shortcut, 23> Config::default_hotkeys{{
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut, true}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("="), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut, true}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change GPU Accuracy")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit yuzu")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral("R+Plus+Minus"), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral("L+Plus+Minus"), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Filter Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Framerate Limit")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Mouse Panning")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Renderdoc Capture")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral(""), QStringLiteral(""), Qt::ApplicationShortcut, false}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Status Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+S"), QStringLiteral(""), Qt::WindowShortcut, false}},
-}};
-// clang-format on
-
-void Config::Initialize(const std::string& config_name) {
- const auto fs_config_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir);
- const auto config_file = fmt::format("{}.ini", config_name);
-
- switch (type) {
- case ConfigType::GlobalConfig:
- qt_config_loc = FS::PathToUTF8String(fs_config_loc / config_file);
- void(FS::CreateParentDir(qt_config_loc));
- qt_config = std::make_unique<QSettings>(QString::fromStdString(qt_config_loc),
- QSettings::IniFormat);
- Reload();
- break;
- case ConfigType::PerGameConfig:
- qt_config_loc =
- FS::PathToUTF8String(fs_config_loc / "custom" / FS::ToU8String(config_file));
- void(FS::CreateParentDir(qt_config_loc));
- qt_config = std::make_unique<QSettings>(QString::fromStdString(qt_config_loc),
- QSettings::IniFormat);
- Reload();
- break;
- case ConfigType::InputProfile:
- qt_config_loc = FS::PathToUTF8String(fs_config_loc / "input" / config_file);
- void(FS::CreateParentDir(qt_config_loc));
- qt_config = std::make_unique<QSettings>(QString::fromStdString(qt_config_loc),
- QSettings::IniFormat);
- break;
- }
-}
-
-bool Config::IsCustomConfig() {
- return type == ConfigType::PerGameConfig;
-}
-
-void Config::ReadPlayerValue(std::size_t player_index) {
- const QString player_prefix = [this, player_index] {
- if (type == ConfigType::InputProfile) {
- return QString{};
- } else {
- return QStringLiteral("player_%1_").arg(player_index);
- }
- }();
-
- auto& player = Settings::values.players.GetValue()[player_index];
- if (IsCustomConfig()) {
- const auto profile_name =
- qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{})
- .toString()
- .toStdString();
- if (profile_name.empty()) {
- // Use the global input config
- player = Settings::values.players.GetValue(true)[player_index];
- return;
- }
- player.profile_name = profile_name;
- }
-
- if (player_prefix.isEmpty() && Settings::IsConfiguringGlobal()) {
- const auto controller = static_cast<Settings::ControllerType>(
- qt_config
- ->value(QStringLiteral("%1type").arg(player_prefix),
- static_cast<u8>(Settings::ControllerType::ProController))
- .toUInt());
-
- if (controller == Settings::ControllerType::LeftJoycon ||
- controller == Settings::ControllerType::RightJoycon) {
- player.controller_type = controller;
- }
- } else {
- player.connected =
- ReadSetting(QStringLiteral("%1connected").arg(player_prefix), player_index == 0)
- .toBool();
-
- player.controller_type = static_cast<Settings::ControllerType>(
- qt_config
- ->value(QStringLiteral("%1type").arg(player_prefix),
- static_cast<u8>(Settings::ControllerType::ProController))
- .toUInt());
-
- player.vibration_enabled =
- qt_config->value(QStringLiteral("%1vibration_enabled").arg(player_prefix), true)
- .toBool();
-
- player.vibration_strength =
- qt_config->value(QStringLiteral("%1vibration_strength").arg(player_prefix), 100)
- .toInt();
-
- player.body_color_left = qt_config
- ->value(QStringLiteral("%1body_color_left").arg(player_prefix),
- Settings::JOYCON_BODY_NEON_BLUE)
- .toUInt();
- player.body_color_right =
- qt_config
- ->value(QStringLiteral("%1body_color_right").arg(player_prefix),
- Settings::JOYCON_BODY_NEON_RED)
- .toUInt();
- player.button_color_left =
- qt_config
- ->value(QStringLiteral("%1button_color_left").arg(player_prefix),
- Settings::JOYCON_BUTTONS_NEON_BLUE)
- .toUInt();
- player.button_color_right =
- qt_config
- ->value(QStringLiteral("%1button_color_right").arg(player_prefix),
- Settings::JOYCON_BUTTONS_NEON_RED)
- .toUInt();
- }
-
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- auto& player_buttons = player.buttons[i];
-
- player_buttons = qt_config
- ->value(QStringLiteral("%1").arg(player_prefix) +
- QString::fromUtf8(Settings::NativeButton::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player_buttons.empty()) {
- player_buttons = default_param;
- }
- }
-
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_stick_mod[i], 0.5f);
- auto& player_analogs = player.analogs[i];
-
- player_analogs = qt_config
- ->value(QStringLiteral("%1").arg(player_prefix) +
- QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player_analogs.empty()) {
- player_analogs = default_param;
- }
- }
-
- for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
- auto& player_motions = player.motions[i];
-
- player_motions = qt_config
- ->value(QStringLiteral("%1").arg(player_prefix) +
- QString::fromUtf8(Settings::NativeMotion::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player_motions.empty()) {
- player_motions = default_param;
- }
- }
-}
-
-void Config::ReadDebugValues() {
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- auto& debug_pad_buttons = Settings::values.debug_pad_buttons[i];
-
- debug_pad_buttons = qt_config
- ->value(QStringLiteral("debug_pad_") +
- QString::fromUtf8(Settings::NativeButton::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (debug_pad_buttons.empty()) {
- debug_pad_buttons = default_param;
- }
- }
-
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_stick_mod[i], 0.5f);
- auto& debug_pad_analogs = Settings::values.debug_pad_analogs[i];
-
- debug_pad_analogs = qt_config
- ->value(QStringLiteral("debug_pad_") +
- QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (debug_pad_analogs.empty()) {
- debug_pad_analogs = default_param;
- }
- }
-}
-
-void Config::ReadTouchscreenValues() {
- Settings::values.touchscreen.enabled =
- ReadSetting(QStringLiteral("touchscreen_enabled"), true).toBool();
-
- Settings::values.touchscreen.rotation_angle =
- ReadSetting(QStringLiteral("touchscreen_angle"), 0).toUInt();
- Settings::values.touchscreen.diameter_x =
- ReadSetting(QStringLiteral("touchscreen_diameter_x"), 15).toUInt();
- Settings::values.touchscreen.diameter_y =
- ReadSetting(QStringLiteral("touchscreen_diameter_y"), 15).toUInt();
-}
-
-void Config::ReadHidbusValues() {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- 0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
- auto& ringcon_analogs = Settings::values.ringcon_analogs;
-
- ringcon_analogs =
- qt_config->value(QStringLiteral("ring_controller"), QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (ringcon_analogs.empty()) {
- ringcon_analogs = default_param;
- }
-}
-
-void Config::ReadAudioValues() {
- qt_config->beginGroup(QStringLiteral("Audio"));
-
- ReadCategory(Settings::Category::Audio);
-
- qt_config->endGroup();
-}
-
-void Config::ReadControlValues() {
- qt_config->beginGroup(QStringLiteral("Controls"));
-
- ReadCategory(Settings::Category::Controls);
-
- Settings::values.players.SetGlobal(!IsCustomConfig());
- for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
- ReadPlayerValue(p);
- }
-
- // Disable docked mode if handheld is selected
- const auto controller_type = Settings::values.players.GetValue()[0].controller_type;
- if (controller_type == Settings::ControllerType::Handheld) {
- Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig());
- Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld);
- }
-
- if (IsCustomConfig()) {
- qt_config->endGroup();
- return;
- }
- ReadDebugValues();
- ReadTouchscreenValues();
- ReadMotionTouchValues();
- ReadHidbusValues();
-
- qt_config->endGroup();
-}
-
-void Config::ReadMotionTouchValues() {
- int num_touch_from_button_maps =
- qt_config->beginReadArray(QStringLiteral("touch_from_button_maps"));
-
- if (num_touch_from_button_maps > 0) {
- const auto append_touch_from_button_map = [this] {
- Settings::TouchFromButtonMap map;
- map.name = ReadSetting(QStringLiteral("name"), QStringLiteral("default"))
- .toString()
- .toStdString();
- const int num_touch_maps = qt_config->beginReadArray(QStringLiteral("entries"));
- map.buttons.reserve(num_touch_maps);
- for (int i = 0; i < num_touch_maps; i++) {
- qt_config->setArrayIndex(i);
- std::string touch_mapping =
- ReadSetting(QStringLiteral("bind")).toString().toStdString();
- map.buttons.emplace_back(std::move(touch_mapping));
- }
- qt_config->endArray(); // entries
- Settings::values.touch_from_button_maps.emplace_back(std::move(map));
- };
-
- for (int i = 0; i < num_touch_from_button_maps; ++i) {
- qt_config->setArrayIndex(i);
- append_touch_from_button_map();
- }
- } else {
- Settings::values.touch_from_button_maps.emplace_back(
- Settings::TouchFromButtonMap{"default", {}});
- num_touch_from_button_maps = 1;
- }
- qt_config->endArray();
-
- Settings::values.touch_from_button_map_index = std::clamp(
- Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
-}
-
-void Config::ReadCoreValues() {
- qt_config->beginGroup(QStringLiteral("Core"));
-
- ReadCategory(Settings::Category::Core);
-
- qt_config->endGroup();
-}
-
-void Config::ReadDataStorageValues() {
- qt_config->beginGroup(QStringLiteral("Data Storage"));
-
- FS::SetYuzuPath(
- FS::YuzuPath::NANDDir,
- qt_config
- ->value(QStringLiteral("nand_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)))
- .toString()
- .toStdString());
- FS::SetYuzuPath(
- FS::YuzuPath::SDMCDir,
- qt_config
- ->value(QStringLiteral("sdmc_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)))
- .toString()
- .toStdString());
- FS::SetYuzuPath(
- FS::YuzuPath::LoadDir,
- qt_config
- ->value(QStringLiteral("load_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)))
- .toString()
- .toStdString());
- FS::SetYuzuPath(
- FS::YuzuPath::DumpDir,
- qt_config
- ->value(QStringLiteral("dump_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)))
- .toString()
- .toStdString());
- FS::SetYuzuPath(FS::YuzuPath::TASDir,
- qt_config
- ->value(QStringLiteral("tas_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::TASDir)))
- .toString()
- .toStdString());
-
- ReadCategory(Settings::Category::DataStorage);
-
- qt_config->endGroup();
-}
-
-void Config::ReadDebuggingValues() {
- qt_config->beginGroup(QStringLiteral("Debugging"));
-
- // Intentionally not using the QT default setting as this is intended to be changed in the ini
- Settings::values.record_frame_times =
- qt_config->value(QStringLiteral("record_frame_times"), false).toBool();
-
- ReadCategory(Settings::Category::Debugging);
- ReadCategory(Settings::Category::DebuggingGraphics);
-
- qt_config->endGroup();
-}
-
-void Config::ReadServiceValues() {
- qt_config->beginGroup(QStringLiteral("Services"));
-
- ReadCategory(Settings::Category::Services);
-
- qt_config->endGroup();
-}
-
-void Config::ReadDisabledAddOnValues() {
- const auto size = qt_config->beginReadArray(QStringLiteral("DisabledAddOns"));
-
- for (int i = 0; i < size; ++i) {
- qt_config->setArrayIndex(i);
- const auto title_id = ReadSetting(QStringLiteral("title_id"), 0).toULongLong();
- std::vector<std::string> out;
- const auto d_size = qt_config->beginReadArray(QStringLiteral("disabled"));
- for (int j = 0; j < d_size; ++j) {
- qt_config->setArrayIndex(j);
- out.push_back(ReadSetting(QStringLiteral("d"), QString{}).toString().toStdString());
- }
- qt_config->endArray();
- Settings::values.disabled_addons.insert_or_assign(title_id, out);
- }
-
- qt_config->endArray();
-}
-
-void Config::ReadMiscellaneousValues() {
- qt_config->beginGroup(QStringLiteral("Miscellaneous"));
-
- ReadCategory(Settings::Category::Miscellaneous);
-
- qt_config->endGroup();
-}
-
-void Config::ReadPathValues() {
- qt_config->beginGroup(QStringLiteral("Paths"));
-
- UISettings::values.roms_path = ReadSetting(QStringLiteral("romsPath")).toString();
- UISettings::values.symbols_path = ReadSetting(QStringLiteral("symbolsPath")).toString();
- UISettings::values.game_dir_deprecated =
- ReadSetting(QStringLiteral("gameListRootDir"), QStringLiteral(".")).toString();
- UISettings::values.game_dir_deprecated_deepscan =
- ReadSetting(QStringLiteral("gameListDeepScan"), false).toBool();
- const int gamedirs_size = qt_config->beginReadArray(QStringLiteral("gamedirs"));
- for (int i = 0; i < gamedirs_size; ++i) {
- qt_config->setArrayIndex(i);
- UISettings::GameDir game_dir;
- game_dir.path = ReadSetting(QStringLiteral("path")).toString();
- game_dir.deep_scan = ReadSetting(QStringLiteral("deep_scan"), false).toBool();
- game_dir.expanded = ReadSetting(QStringLiteral("expanded"), true).toBool();
- UISettings::values.game_dirs.append(game_dir);
- }
- qt_config->endArray();
- // create NAND and SD card directories if empty, these are not removable through the UI,
- // also carries over old game list settings if present
- if (UISettings::values.game_dirs.isEmpty()) {
- UISettings::GameDir game_dir;
- game_dir.path = QStringLiteral("SDMC");
- game_dir.expanded = true;
- UISettings::values.game_dirs.append(game_dir);
- game_dir.path = QStringLiteral("UserNAND");
- UISettings::values.game_dirs.append(game_dir);
- game_dir.path = QStringLiteral("SysNAND");
- UISettings::values.game_dirs.append(game_dir);
- if (UISettings::values.game_dir_deprecated != QStringLiteral(".")) {
- game_dir.path = UISettings::values.game_dir_deprecated;
- game_dir.deep_scan = UISettings::values.game_dir_deprecated_deepscan;
- UISettings::values.game_dirs.append(game_dir);
- }
- }
- UISettings::values.recent_files = ReadSetting(QStringLiteral("recentFiles")).toStringList();
- UISettings::values.language = ReadSetting(QStringLiteral("language"), QString{}).toString();
-
- qt_config->endGroup();
-}
-
-void Config::ReadCpuValues() {
- qt_config->beginGroup(QStringLiteral("Cpu"));
-
- ReadCategory(Settings::Category::Cpu);
- ReadCategory(Settings::Category::CpuDebug);
- ReadCategory(Settings::Category::CpuUnsafe);
-
- qt_config->endGroup();
-}
-
-void Config::ReadRendererValues() {
- qt_config->beginGroup(QStringLiteral("Renderer"));
-
- ReadCategory(Settings::Category::Renderer);
- ReadCategory(Settings::Category::RendererAdvanced);
- ReadCategory(Settings::Category::RendererDebug);
-
- qt_config->endGroup();
-}
-
-void Config::ReadScreenshotValues() {
- qt_config->beginGroup(QStringLiteral("Screenshots"));
-
- ReadCategory(Settings::Category::Screenshots);
- FS::SetYuzuPath(
- FS::YuzuPath::ScreenshotsDir,
- qt_config
- ->value(QStringLiteral("screenshot_path"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir)))
- .toString()
- .toStdString());
-
- qt_config->endGroup();
-}
-
-void Config::ReadShortcutValues() {
- qt_config->beginGroup(QStringLiteral("Shortcuts"));
-
- for (const auto& [name, group, shortcut] : default_hotkeys) {
- qt_config->beginGroup(group);
- qt_config->beginGroup(name);
- // No longer using ReadSetting for shortcut.second as it inaccurately returns a value of 1
- // for WidgetWithChildrenShortcut which is a value of 3. Needed to fix shortcuts the open
- // a file dialog in windowed mode
- UISettings::values.shortcuts.push_back(
- {name,
- group,
- {ReadSetting(QStringLiteral("KeySeq"), shortcut.keyseq).toString(),
- ReadSetting(QStringLiteral("Controller_KeySeq"), shortcut.controller_keyseq)
- .toString(),
- shortcut.context, ReadSetting(QStringLiteral("Repeat"), shortcut.repeat).toBool()}});
- qt_config->endGroup();
- qt_config->endGroup();
- }
-
- qt_config->endGroup();
-}
-
-void Config::ReadSystemValues() {
- qt_config->beginGroup(QStringLiteral("System"));
-
- ReadCategory(Settings::Category::System);
- ReadCategory(Settings::Category::SystemAudio);
-
- qt_config->endGroup();
-}
-
-void Config::ReadUIValues() {
- qt_config->beginGroup(QStringLiteral("UI"));
-
- UISettings::values.theme =
- ReadSetting(
- QStringLiteral("theme"),
- QString::fromUtf8(UISettings::themes[static_cast<size_t>(default_theme)].second))
- .toString();
-
- ReadUIGamelistValues();
- ReadUILayoutValues();
- ReadPathValues();
- ReadScreenshotValues();
- ReadShortcutValues();
- ReadMultiplayerValues();
-
- ReadCategory(Settings::Category::Ui);
- ReadCategory(Settings::Category::UiGeneral);
-
- qt_config->endGroup();
-}
-
-void Config::ReadUIGamelistValues() {
- qt_config->beginGroup(QStringLiteral("UIGameList"));
-
- ReadCategory(Settings::Category::UiGameList);
-
- const int favorites_size = qt_config->beginReadArray(QStringLiteral("favorites"));
- for (int i = 0; i < favorites_size; i++) {
- qt_config->setArrayIndex(i);
- UISettings::values.favorited_ids.append(
- ReadSetting(QStringLiteral("program_id")).toULongLong());
- }
- qt_config->endArray();
-
- qt_config->endGroup();
-}
-
-void Config::ReadUILayoutValues() {
- qt_config->beginGroup(QStringLiteral("UILayout"));
-
- UISettings::values.geometry = ReadSetting(QStringLiteral("geometry")).toByteArray();
- UISettings::values.state = ReadSetting(QStringLiteral("state")).toByteArray();
- UISettings::values.renderwindow_geometry =
- ReadSetting(QStringLiteral("geometryRenderWindow")).toByteArray();
- UISettings::values.gamelist_header_state =
- ReadSetting(QStringLiteral("gameListHeaderState")).toByteArray();
- UISettings::values.microprofile_geometry =
- ReadSetting(QStringLiteral("microProfileDialogGeometry")).toByteArray();
-
- ReadCategory(Settings::Category::UiLayout);
-
- qt_config->endGroup();
-}
-
-void Config::ReadWebServiceValues() {
- qt_config->beginGroup(QStringLiteral("WebService"));
-
- ReadCategory(Settings::Category::WebService);
-
- qt_config->endGroup();
-}
-
-void Config::ReadMultiplayerValues() {
- qt_config->beginGroup(QStringLiteral("Multiplayer"));
-
- ReadCategory(Settings::Category::Multiplayer);
-
- // Read ban list back
- int size = qt_config->beginReadArray(QStringLiteral("username_ban_list"));
- UISettings::values.multiplayer_ban_list.first.resize(size);
- for (int i = 0; i < size; ++i) {
- qt_config->setArrayIndex(i);
- UISettings::values.multiplayer_ban_list.first[i] =
- ReadSetting(QStringLiteral("username")).toString().toStdString();
- }
- qt_config->endArray();
- size = qt_config->beginReadArray(QStringLiteral("ip_ban_list"));
- UISettings::values.multiplayer_ban_list.second.resize(size);
- for (int i = 0; i < size; ++i) {
- qt_config->setArrayIndex(i);
- UISettings::values.multiplayer_ban_list.second[i] =
- ReadSetting(QStringLiteral("ip")).toString().toStdString();
- }
- qt_config->endArray();
-
- qt_config->endGroup();
-}
-
-void Config::ReadNetworkValues() {
- qt_config->beginGroup(QString::fromStdString("Services"));
-
- ReadCategory(Settings::Category::Network);
-
- qt_config->endGroup();
-}
-
-void Config::ReadValues() {
- if (global) {
- ReadDataStorageValues();
- ReadDebuggingValues();
- ReadDisabledAddOnValues();
- ReadNetworkValues();
- ReadServiceValues();
- ReadUIValues();
- ReadWebServiceValues();
- ReadMiscellaneousValues();
- }
- ReadControlValues();
- ReadCoreValues();
- ReadCpuValues();
- ReadRendererValues();
- ReadAudioValues();
- ReadSystemValues();
-}
-
-void Config::SavePlayerValue(std::size_t player_index) {
- const QString player_prefix = [this, player_index] {
- if (type == ConfigType::InputProfile) {
- return QString{};
- } else {
- return QStringLiteral("player_%1_").arg(player_index);
- }
- }();
-
- const auto& player = Settings::values.players.GetValue()[player_index];
- if (IsCustomConfig()) {
- if (player.profile_name.empty()) {
- // No custom profile selected
- return;
- }
- WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix),
- QString::fromStdString(player.profile_name), QString{});
- }
-
- WriteSetting(QStringLiteral("%1type").arg(player_prefix),
- static_cast<u8>(player.controller_type),
- static_cast<u8>(Settings::ControllerType::ProController));
-
- if (!player_prefix.isEmpty() || !Settings::IsConfiguringGlobal()) {
- WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected,
- player_index == 0);
- WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix),
- player.vibration_enabled, true);
- WriteSetting(QStringLiteral("%1vibration_strength").arg(player_prefix),
- player.vibration_strength, 100);
- WriteSetting(QStringLiteral("%1body_color_left").arg(player_prefix), player.body_color_left,
- Settings::JOYCON_BODY_NEON_BLUE);
- WriteSetting(QStringLiteral("%1body_color_right").arg(player_prefix),
- player.body_color_right, Settings::JOYCON_BODY_NEON_RED);
- WriteSetting(QStringLiteral("%1button_color_left").arg(player_prefix),
- player.button_color_left, Settings::JOYCON_BUTTONS_NEON_BLUE);
- WriteSetting(QStringLiteral("%1button_color_right").arg(player_prefix),
- player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED);
- }
-
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- WriteSetting(QStringLiteral("%1").arg(player_prefix) +
- QString::fromStdString(Settings::NativeButton::mapping[i]),
- QString::fromStdString(player.buttons[i]),
- QString::fromStdString(default_param));
- }
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_stick_mod[i], 0.5f);
- WriteSetting(QStringLiteral("%1").arg(player_prefix) +
- QString::fromStdString(Settings::NativeAnalog::mapping[i]),
- QString::fromStdString(player.analogs[i]),
- QString::fromStdString(default_param));
- }
- for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
- WriteSetting(QStringLiteral("%1").arg(player_prefix) +
- QString::fromStdString(Settings::NativeMotion::mapping[i]),
- QString::fromStdString(player.motions[i]),
- QString::fromStdString(default_param));
- }
-}
-
-void Config::SaveDebugValues() {
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- WriteSetting(QStringLiteral("debug_pad_") +
- QString::fromStdString(Settings::NativeButton::mapping[i]),
- QString::fromStdString(Settings::values.debug_pad_buttons[i]),
- QString::fromStdString(default_param));
- }
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_stick_mod[i], 0.5f);
- WriteSetting(QStringLiteral("debug_pad_") +
- QString::fromStdString(Settings::NativeAnalog::mapping[i]),
- QString::fromStdString(Settings::values.debug_pad_analogs[i]),
- QString::fromStdString(default_param));
- }
-}
-
-void Config::SaveTouchscreenValues() {
- const auto& touchscreen = Settings::values.touchscreen;
-
- WriteSetting(QStringLiteral("touchscreen_enabled"), touchscreen.enabled, true);
-
- WriteSetting(QStringLiteral("touchscreen_angle"), touchscreen.rotation_angle, 0);
- WriteSetting(QStringLiteral("touchscreen_diameter_x"), touchscreen.diameter_x, 15);
- WriteSetting(QStringLiteral("touchscreen_diameter_y"), touchscreen.diameter_y, 15);
-}
-
-void Config::SaveMotionTouchValues() {
- qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));
- for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
- qt_config->setArrayIndex(static_cast<int>(p));
- WriteSetting(QStringLiteral("name"),
- QString::fromStdString(Settings::values.touch_from_button_maps[p].name),
- QStringLiteral("default"));
- qt_config->beginWriteArray(QStringLiteral("entries"));
- for (std::size_t q = 0; q < Settings::values.touch_from_button_maps[p].buttons.size();
- ++q) {
- qt_config->setArrayIndex(static_cast<int>(q));
- WriteSetting(
- QStringLiteral("bind"),
- QString::fromStdString(Settings::values.touch_from_button_maps[p].buttons[q]));
- }
- qt_config->endArray();
- }
- qt_config->endArray();
-}
-
-void Config::SaveHidbusValues() {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- 0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
- WriteSetting(QStringLiteral("ring_controller"),
- QString::fromStdString(Settings::values.ringcon_analogs),
- QString::fromStdString(default_param));
-}
-
-void Config::SaveValues() {
- if (global) {
- SaveDataStorageValues();
- SaveDebuggingValues();
- SaveDisabledAddOnValues();
- SaveNetworkValues();
- SaveUIValues();
- SaveWebServiceValues();
- SaveMiscellaneousValues();
- }
- SaveControlValues();
- SaveCoreValues();
- SaveCpuValues();
- SaveRendererValues();
- SaveAudioValues();
- SaveSystemValues();
-
- qt_config->sync();
-}
-
-void Config::SaveAudioValues() {
- qt_config->beginGroup(QStringLiteral("Audio"));
-
- WriteCategory(Settings::Category::Audio);
-
- qt_config->endGroup();
-}
-
-void Config::SaveControlValues() {
- qt_config->beginGroup(QStringLiteral("Controls"));
-
- WriteCategory(Settings::Category::Controls);
-
- Settings::values.players.SetGlobal(!IsCustomConfig());
- for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
- SavePlayerValue(p);
- }
- if (IsCustomConfig()) {
- qt_config->endGroup();
- return;
- }
- SaveDebugValues();
- SaveTouchscreenValues();
- SaveMotionTouchValues();
- SaveHidbusValues();
-
- qt_config->endGroup();
-}
-
-void Config::SaveCoreValues() {
- qt_config->beginGroup(QStringLiteral("Core"));
-
- WriteCategory(Settings::Category::Core);
-
- qt_config->endGroup();
-}
-
-void Config::SaveDataStorageValues() {
- qt_config->beginGroup(QStringLiteral("Data Storage"));
-
- WriteSetting(QStringLiteral("nand_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
- WriteSetting(QStringLiteral("sdmc_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
- WriteSetting(QStringLiteral("load_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
- WriteSetting(QStringLiteral("dump_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
- WriteSetting(QStringLiteral("tas_directory"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::TASDir)),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::TASDir)));
-
- WriteCategory(Settings::Category::DataStorage);
-
- qt_config->endGroup();
-}
-
-void Config::SaveDebuggingValues() {
- qt_config->beginGroup(QStringLiteral("Debugging"));
-
- // Intentionally not using the QT default setting as this is intended to be changed in the ini
- qt_config->setValue(QStringLiteral("record_frame_times"), Settings::values.record_frame_times);
-
- WriteCategory(Settings::Category::Debugging);
- WriteCategory(Settings::Category::DebuggingGraphics);
-
- qt_config->endGroup();
-}
-
-void Config::SaveNetworkValues() {
- qt_config->beginGroup(QStringLiteral("Services"));
-
- WriteCategory(Settings::Category::Network);
-
- qt_config->endGroup();
-}
-
-void Config::SaveDisabledAddOnValues() {
- qt_config->beginWriteArray(QStringLiteral("DisabledAddOns"));
-
- int i = 0;
- for (const auto& elem : Settings::values.disabled_addons) {
- qt_config->setArrayIndex(i);
- WriteSetting(QStringLiteral("title_id"), QVariant::fromValue<u64>(elem.first), 0);
- qt_config->beginWriteArray(QStringLiteral("disabled"));
- for (std::size_t j = 0; j < elem.second.size(); ++j) {
- qt_config->setArrayIndex(static_cast<int>(j));
- WriteSetting(QStringLiteral("d"), QString::fromStdString(elem.second[j]), QString{});
- }
- qt_config->endArray();
- ++i;
- }
-
- qt_config->endArray();
-}
-
-void Config::SaveMiscellaneousValues() {
- qt_config->beginGroup(QStringLiteral("Miscellaneous"));
-
- WriteCategory(Settings::Category::Miscellaneous);
-
- qt_config->endGroup();
-}
-
-void Config::SavePathValues() {
- qt_config->beginGroup(QStringLiteral("Paths"));
-
- WriteSetting(QStringLiteral("romsPath"), UISettings::values.roms_path);
- WriteSetting(QStringLiteral("symbolsPath"), UISettings::values.symbols_path);
- qt_config->beginWriteArray(QStringLiteral("gamedirs"));
- for (int i = 0; i < UISettings::values.game_dirs.size(); ++i) {
- qt_config->setArrayIndex(i);
- const auto& game_dir = UISettings::values.game_dirs[i];
- WriteSetting(QStringLiteral("path"), game_dir.path);
- WriteSetting(QStringLiteral("deep_scan"), game_dir.deep_scan, false);
- WriteSetting(QStringLiteral("expanded"), game_dir.expanded, true);
- }
- qt_config->endArray();
- WriteSetting(QStringLiteral("recentFiles"), UISettings::values.recent_files);
- WriteSetting(QStringLiteral("language"), UISettings::values.language, QString{});
-
- qt_config->endGroup();
-}
-
-void Config::SaveCpuValues() {
- qt_config->beginGroup(QStringLiteral("Cpu"));
-
- WriteCategory(Settings::Category::Cpu);
- WriteCategory(Settings::Category::CpuDebug);
- WriteCategory(Settings::Category::CpuUnsafe);
-
- qt_config->endGroup();
-}
-
-void Config::SaveRendererValues() {
- qt_config->beginGroup(QStringLiteral("Renderer"));
-
- WriteCategory(Settings::Category::Renderer);
- WriteCategory(Settings::Category::RendererAdvanced);
- WriteCategory(Settings::Category::RendererDebug);
-
- qt_config->endGroup();
-}
-
-void Config::SaveScreenshotValues() {
- qt_config->beginGroup(QStringLiteral("Screenshots"));
-
- WriteSetting(QStringLiteral("screenshot_path"),
- QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir)));
- WriteCategory(Settings::Category::Screenshots);
-
- qt_config->endGroup();
-}
-
-void Config::SaveShortcutValues() {
- qt_config->beginGroup(QStringLiteral("Shortcuts"));
-
- // Lengths of UISettings::values.shortcuts & default_hotkeys are same.
- // However, their ordering must also be the same.
- for (std::size_t i = 0; i < default_hotkeys.size(); i++) {
- const auto& [name, group, shortcut] = UISettings::values.shortcuts[i];
- const auto& default_hotkey = default_hotkeys[i].shortcut;
-
- qt_config->beginGroup(group);
- qt_config->beginGroup(name);
- WriteSetting(QStringLiteral("KeySeq"), shortcut.keyseq, default_hotkey.keyseq);
- WriteSetting(QStringLiteral("Controller_KeySeq"), shortcut.controller_keyseq,
- default_hotkey.controller_keyseq);
- WriteSetting(QStringLiteral("Context"), shortcut.context, default_hotkey.context);
- WriteSetting(QStringLiteral("Repeat"), shortcut.repeat, default_hotkey.repeat);
- qt_config->endGroup();
- qt_config->endGroup();
- }
-
- qt_config->endGroup();
-}
-
-void Config::SaveSystemValues() {
- qt_config->beginGroup(QStringLiteral("System"));
-
- WriteCategory(Settings::Category::System);
- WriteCategory(Settings::Category::SystemAudio);
-
- qt_config->endGroup();
-}
-
-void Config::SaveUIValues() {
- qt_config->beginGroup(QStringLiteral("UI"));
-
- WriteCategory(Settings::Category::Ui);
- WriteCategory(Settings::Category::UiGeneral);
-
- WriteSetting(QStringLiteral("theme"), UISettings::values.theme,
- QString::fromUtf8(UISettings::themes[static_cast<size_t>(default_theme)].second));
-
- SaveUIGamelistValues();
- SaveUILayoutValues();
- SavePathValues();
- SaveScreenshotValues();
- SaveShortcutValues();
- SaveMultiplayerValues();
-
- qt_config->endGroup();
-}
-
-void Config::SaveUIGamelistValues() {
- qt_config->beginGroup(QStringLiteral("UIGameList"));
-
- WriteCategory(Settings::Category::UiGameList);
-
- qt_config->beginWriteArray(QStringLiteral("favorites"));
- for (int i = 0; i < UISettings::values.favorited_ids.size(); i++) {
- qt_config->setArrayIndex(i);
- WriteSetting(QStringLiteral("program_id"),
- QVariant::fromValue(UISettings::values.favorited_ids[i]));
- }
- qt_config->endArray();
-
- qt_config->endGroup();
-}
-
-void Config::SaveUILayoutValues() {
- qt_config->beginGroup(QStringLiteral("UILayout"));
-
- WriteSetting(QStringLiteral("geometry"), UISettings::values.geometry);
- WriteSetting(QStringLiteral("state"), UISettings::values.state);
- WriteSetting(QStringLiteral("geometryRenderWindow"), UISettings::values.renderwindow_geometry);
- WriteSetting(QStringLiteral("gameListHeaderState"), UISettings::values.gamelist_header_state);
- WriteSetting(QStringLiteral("microProfileDialogGeometry"),
- UISettings::values.microprofile_geometry);
-
- WriteCategory(Settings::Category::UiLayout);
-
- qt_config->endGroup();
-}
-
-void Config::SaveWebServiceValues() {
- qt_config->beginGroup(QStringLiteral("WebService"));
-
- WriteCategory(Settings::Category::WebService);
-
- qt_config->endGroup();
-}
-
-void Config::SaveMultiplayerValues() {
- qt_config->beginGroup(QStringLiteral("Multiplayer"));
-
- WriteCategory(Settings::Category::Multiplayer);
-
- // Write ban list
- qt_config->beginWriteArray(QStringLiteral("username_ban_list"));
- for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.first.size(); ++i) {
- qt_config->setArrayIndex(static_cast<int>(i));
- WriteSetting(QStringLiteral("username"),
- QString::fromStdString(UISettings::values.multiplayer_ban_list.first[i]));
- }
- qt_config->endArray();
- qt_config->beginWriteArray(QStringLiteral("ip_ban_list"));
- for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.second.size(); ++i) {
- qt_config->setArrayIndex(static_cast<int>(i));
- WriteSetting(QStringLiteral("ip"),
- QString::fromStdString(UISettings::values.multiplayer_ban_list.second[i]));
- }
- qt_config->endArray();
-
- qt_config->endGroup();
-}
-
-QVariant Config::ReadSetting(const QString& name) const {
- return qt_config->value(name);
-}
-
-QVariant Config::ReadSetting(const QString& name, const QVariant& default_value) const {
- QVariant result;
- if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
- result = default_value;
- } else {
- result = qt_config->value(name, default_value);
- }
- return result;
-}
-
-void Config::WriteSetting(const QString& name, const QVariant& value) {
- qt_config->setValue(name, value);
-}
-
-void Config::WriteSetting(const QString& name, const QVariant& value,
- const QVariant& default_value) {
- qt_config->setValue(name + QStringLiteral("/default"), value == default_value);
- qt_config->setValue(name, value);
-}
-
-void Config::WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
- bool use_global) {
- if (!global) {
- qt_config->setValue(name + QStringLiteral("/use_global"), use_global);
- }
- if (global || !use_global) {
- qt_config->setValue(name + QStringLiteral("/default"), value == default_value);
- qt_config->setValue(name, value);
- }
-}
-
-void Config::Reload() {
- ReadValues();
- // To apply default value changes
- SaveValues();
-}
-
-void Config::Save() {
- SaveValues();
-}
-
-void Config::ReadControlPlayerValue(std::size_t player_index) {
- qt_config->beginGroup(QStringLiteral("Controls"));
- ReadPlayerValue(player_index);
- qt_config->endGroup();
-}
-
-void Config::SaveControlPlayerValue(std::size_t player_index) {
- qt_config->beginGroup(QStringLiteral("Controls"));
- SavePlayerValue(player_index);
- qt_config->endGroup();
-}
-
-void Config::ClearControlPlayerValues() {
- qt_config->beginGroup(QStringLiteral("Controls"));
- // If key is an empty string, all keys in the current group() are removed.
- qt_config->remove(QString{});
- qt_config->endGroup();
-}
-
-const std::string& Config::GetConfigFilePath() const {
- return qt_config_loc;
-}
-
-static auto FindRelevantList(Settings::Category category) {
- auto& map = Settings::values.linkage.by_category;
- if (map.contains(category)) {
- return Settings::values.linkage.by_category[category];
- }
- return UISettings::values.linkage.by_category[category];
-}
-
-void Config::ReadCategory(Settings::Category category) {
- const auto& settings = FindRelevantList(category);
- std::for_each(settings.begin(), settings.end(),
- [&](const auto& setting) { ReadSettingGeneric(setting); });
-}
-
-void Config::WriteCategory(Settings::Category category) {
- const auto& settings = FindRelevantList(category);
- std::for_each(settings.begin(), settings.end(),
- [&](const auto& setting) { WriteSettingGeneric(setting); });
-}
-
-void Config::ReadSettingGeneric(Settings::BasicSetting* const setting) {
- if (!setting->Save() || (!setting->Switchable() && !global)) {
- return;
- }
- const QString name = QString::fromStdString(setting->GetLabel());
- const auto default_value =
- QVariant::fromValue<QString>(QString::fromStdString(setting->DefaultToString()));
-
- bool use_global = true;
- if (setting->Switchable() && !global) {
- use_global = qt_config->value(name + QStringLiteral("/use_global"), true).value<bool>();
- setting->SetGlobal(use_global);
- }
-
- if (global || !use_global) {
- const bool is_default =
- qt_config->value(name + QStringLiteral("/default"), true).value<bool>();
- if (!is_default) {
- setting->LoadString(
- qt_config->value(name, default_value).value<QString>().toStdString());
- } else {
- // Empty string resets the Setting to default
- setting->LoadString("");
- }
- }
-}
-
-void Config::WriteSettingGeneric(Settings::BasicSetting* const setting) const {
- if (!setting->Save()) {
- return;
- }
- const QVariant value = QVariant::fromValue(QString::fromStdString(setting->ToString()));
- const QVariant default_value =
- QVariant::fromValue(QString::fromStdString(setting->DefaultToString()));
- const QString label = QString::fromStdString(setting->GetLabel());
- if (setting->Switchable()) {
- if (!global) {
- qt_config->setValue(label + QStringLiteral("/use_global"), setting->UsingGlobal());
- }
- if (global || !setting->UsingGlobal()) {
- qt_config->setValue(label + QStringLiteral("/default"), value == default_value);
- qt_config->setValue(label, value);
- }
- } else if (global) {
- qt_config->setValue(label + QStringLiteral("/default"), value == default_value);
- qt_config->setValue(label, value);
- }
-}
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
deleted file mode 100644
index 74ec4f771..000000000
--- a/src/yuzu/configuration/config.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// SPDX-FileCopyrightText: 2014 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <memory>
-#include <string>
-#include <QMetaType>
-#include <QVariant>
-#include "common/settings.h"
-#include "common/settings_enums.h"
-#include "yuzu/uisettings.h"
-
-class QSettings;
-
-namespace Core {
-class System;
-}
-
-class Config {
-public:
- enum class ConfigType {
- GlobalConfig,
- PerGameConfig,
- InputProfile,
- };
-
- explicit Config(const std::string& config_name = "qt-config",
- ConfigType config_type = ConfigType::GlobalConfig);
- ~Config();
-
- void Reload();
- void Save();
-
- void ReadControlPlayerValue(std::size_t player_index);
- void SaveControlPlayerValue(std::size_t player_index);
- void ClearControlPlayerValues();
-
- const std::string& GetConfigFilePath() const;
-
- static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
- static const std::array<int, Settings::NativeMotion::NumMotions> default_motions;
- static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs;
- static const std::array<int, 2> default_stick_mod;
- static const std::array<int, 2> default_ringcon_analogs;
- static const std::array<int, Settings::NativeMouseButton::NumMouseButtons>
- default_mouse_buttons;
- static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys;
- static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods;
- static const std::array<UISettings::Shortcut, 23> default_hotkeys;
-
- static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map;
- static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map;
- static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map;
- static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map;
- static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map;
- static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map;
-
- static constexpr UISettings::Theme default_theme{
-#ifdef _WIN32
- UISettings::Theme::DarkColorful
-#else
- UISettings::Theme::DefaultColorful
-#endif
- };
-
-private:
- void Initialize(const std::string& config_name);
- bool IsCustomConfig();
-
- void ReadValues();
- void ReadPlayerValue(std::size_t player_index);
- void ReadDebugValues();
- void ReadKeyboardValues();
- void ReadMouseValues();
- void ReadTouchscreenValues();
- void ReadMotionTouchValues();
- void ReadHidbusValues();
- void ReadIrCameraValues();
-
- // Read functions bases off the respective config section names.
- void ReadAudioValues();
- void ReadControlValues();
- void ReadCoreValues();
- void ReadDataStorageValues();
- void ReadDebuggingValues();
- void ReadServiceValues();
- void ReadDisabledAddOnValues();
- void ReadMiscellaneousValues();
- void ReadPathValues();
- void ReadCpuValues();
- void ReadRendererValues();
- void ReadScreenshotValues();
- void ReadShortcutValues();
- void ReadSystemValues();
- void ReadUIValues();
- void ReadUIGamelistValues();
- void ReadUILayoutValues();
- void ReadWebServiceValues();
- void ReadMultiplayerValues();
- void ReadNetworkValues();
-
- void SaveValues();
- void SavePlayerValue(std::size_t player_index);
- void SaveDebugValues();
- void SaveMouseValues();
- void SaveTouchscreenValues();
- void SaveMotionTouchValues();
- void SaveHidbusValues();
- void SaveIrCameraValues();
-
- // Save functions based off the respective config section names.
- void SaveAudioValues();
- void SaveControlValues();
- void SaveCoreValues();
- void SaveDataStorageValues();
- void SaveDebuggingValues();
- void SaveNetworkValues();
- void SaveDisabledAddOnValues();
- void SaveMiscellaneousValues();
- void SavePathValues();
- void SaveCpuValues();
- void SaveRendererValues();
- void SaveScreenshotValues();
- void SaveShortcutValues();
- void SaveSystemValues();
- void SaveUIValues();
- void SaveUIGamelistValues();
- void SaveUILayoutValues();
- void SaveWebServiceValues();
- void SaveMultiplayerValues();
-
- /**
- * Reads a setting from the qt_config.
- *
- * @param name The setting's identifier
- * @param default_value The value to use when the setting is not already present in the config
- */
- QVariant ReadSetting(const QString& name) const;
- QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
-
- /**
- * Writes a setting to the qt_config.
- *
- * @param name The setting's idetentifier
- * @param value Value of the setting
- * @param default_value Default of the setting if not present in qt_config
- * @param use_global Specifies if the custom or global config should be in use, for custom
- * configs
- */
- void WriteSetting(const QString& name, const QVariant& value);
- void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
- void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
- bool use_global);
-
- void ReadCategory(Settings::Category category);
- void WriteCategory(Settings::Category category);
- void ReadSettingGeneric(Settings::BasicSetting* const setting);
- void WriteSettingGeneric(Settings::BasicSetting* const setting) const;
-
- const ConfigType type;
- std::unique_ptr<QSettings> qt_config;
- std::string qt_config_loc;
- const bool global;
-};
-
-// These metatype declarations cannot be in common/settings.h because core is devoid of QT
-Q_DECLARE_METATYPE(Settings::CpuAccuracy);
-Q_DECLARE_METATYPE(Settings::GpuAccuracy);
-Q_DECLARE_METATYPE(Settings::FullscreenMode);
-Q_DECLARE_METATYPE(Settings::NvdecEmulation);
-Q_DECLARE_METATYPE(Settings::ResolutionSetup);
-Q_DECLARE_METATYPE(Settings::ScalingFilter);
-Q_DECLARE_METATYPE(Settings::AntiAliasing);
-Q_DECLARE_METATYPE(Settings::RendererBackend);
-Q_DECLARE_METATYPE(Settings::ShaderBackend);
-Q_DECLARE_METATYPE(Settings::AstcRecompression);
-Q_DECLARE_METATYPE(Settings::AstcDecodeMode);
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index 81dd51ad3..9b6ef47a7 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -38,17 +38,21 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
std::map<u32, QWidget*> hold;
- auto push = [&](Settings::Category category) {
+ auto push_settings = [&](Settings::Category category) {
for (auto* setting : Settings::values.linkage.by_category[category]) {
settings.push_back(setting);
}
+ };
+
+ auto push_ui_settings = [&](Settings::Category category) {
for (auto* setting : UISettings::values.linkage.by_category[category]) {
settings.push_back(setting);
}
};
- push(Settings::Category::Audio);
- push(Settings::Category::SystemAudio);
+ push_settings(Settings::Category::Audio);
+ push_settings(Settings::Category::SystemAudio);
+ push_ui_settings(Settings::Category::UiAudio);
for (auto* setting : settings) {
auto* widget = builder.BuildWidget(setting, apply_funcs);
diff --git a/src/yuzu/configuration/configure_camera.cpp b/src/yuzu/configuration/configure_camera.cpp
index d95e96696..3368f53f3 100644
--- a/src/yuzu/configuration/configure_camera.cpp
+++ b/src/yuzu/configuration/configure_camera.cpp
@@ -10,10 +10,10 @@
#include <QStandardItemModel>
#include <QTimer>
+#include "common/settings.h"
#include "input_common/drivers/camera.h"
#include "input_common/main.h"
#include "ui_configure_camera.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_camera.h"
ConfigureCamera::ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_)
diff --git a/src/yuzu/configuration/configure_camera.h b/src/yuzu/configuration/configure_camera.h
index 9a90512b3..3d822da7b 100644
--- a/src/yuzu/configuration/configure_camera.h
+++ b/src/yuzu/configuration/configure_camera.h
@@ -1,4 +1,4 @@
-// Text : Copyright 2022 yuzu Emulator Project
+// Text : Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index ef421c754..1010038b7 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -51,6 +51,8 @@ void ConfigureDebug::SetConfiguration() {
ui->enable_all_controllers->setChecked(Settings::values.enable_all_controllers.GetValue());
ui->enable_renderdoc_hotkey->setEnabled(runtime_lock);
ui->enable_renderdoc_hotkey->setChecked(Settings::values.enable_renderdoc_hotkey.GetValue());
+ ui->disable_buffer_reorder->setEnabled(runtime_lock);
+ ui->disable_buffer_reorder->setChecked(Settings::values.disable_buffer_reorder.GetValue());
ui->enable_graphics_debugging->setEnabled(runtime_lock);
ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue());
ui->enable_shader_feedback->setEnabled(runtime_lock);
@@ -96,6 +98,7 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.enable_all_controllers = ui->enable_all_controllers->isChecked();
Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
Settings::values.enable_renderdoc_hotkey = ui->enable_renderdoc_hotkey->isChecked();
+ Settings::values.disable_buffer_reorder = ui->disable_buffer_reorder->isChecked();
Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked();
Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked();
Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked();
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 76fe98924..22b51f39c 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -271,19 +271,6 @@
</widget>
</item>
<item row="8" column="0">
- <widget class="QCheckBox" name="disable_macro_hle">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="toolTip">
- <string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string>
- </property>
- <property name="text">
- <string>Disable Macro HLE</string>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
<widget class="QCheckBox" name="dump_macros">
<property name="enabled">
<bool>true</bool>
@@ -306,17 +293,27 @@
</property>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QCheckBox" name="enable_shader_feedback">
+ <item row="6" column="0">
+ <widget class="QCheckBox" name="dump_shaders">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
<property name="toolTip">
- <string>When checked, yuzu will log statistics about the compiled pipeline cache</string>
+ <string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
</property>
<property name="text">
- <string>Enable Shader Feedback</string>
+ <string>Dump Game Shaders</string>
</property>
</widget>
</item>
- <item row="6" column="0">
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="enable_renderdoc_hotkey">
+ <property name="text">
+ <string>Enable Renderdoc Hotkey</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
<widget class="QCheckBox" name="disable_macro_jit">
<property name="enabled">
<bool>true</bool>
@@ -330,20 +327,17 @@
</widget>
</item>
<item row="9" column="0">
- <spacer name="verticalSpacer_5">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <widget class="QCheckBox" name="disable_macro_hle">
+ <property name="enabled">
+ <bool>true</bool>
</property>
- <property name="sizeType">
- <enum>QSizePolicy::Preferred</enum>
+ <property name="toolTip">
+ <string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>0</height>
- </size>
+ <property name="text">
+ <string>Disable Macro HLE</string>
</property>
- </spacer>
+ </widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="enable_graphics_debugging">
@@ -358,23 +352,39 @@
</property>
</widget>
</item>
- <item row="5" column="0">
- <widget class="QCheckBox" name="dump_shaders">
- <property name="enabled">
- <bool>true</bool>
+ <item row="10" column="0">
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Preferred</enum>
</property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="enable_shader_feedback">
<property name="toolTip">
- <string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
+ <string>When checked, yuzu will log statistics about the compiled pipeline cache</string>
</property>
<property name="text">
- <string>Dump Game Shaders</string>
+ <string>Enable Shader Feedback</string>
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="enable_renderdoc_hotkey">
+ <item row="5" column="0">
+ <widget class="QCheckBox" name="disable_buffer_reorder">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When checked, disables reording of mapped memory uploads which allows to associate uploads with specific draws. May reduce performance in some cases.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
<property name="text">
- <string>Enable Renderdoc Hotkey</string>
+ <string>Disable Buffer Reorder</string>
</property>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 0ad95cc02..aab54a1cc 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -8,7 +8,6 @@
#include "core/core.h"
#include "ui_configure.h"
#include "vk_device_info.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_audio.h"
#include "yuzu/configuration/configure_cpu.h"
#include "yuzu/configuration/configure_debug_tab.h"
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index 68e21cd84..76fc33e49 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -9,10 +9,11 @@
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
+#include "frontend_common/config.h"
#include "ui_configure_hotkeys.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_hotkeys.h"
#include "yuzu/hotkeys.h"
+#include "yuzu/uisettings.h"
#include "yuzu/util/sequence_dialog/sequence_dialog.h"
constexpr int name_column = 0;
@@ -62,18 +63,21 @@ ConfigureHotkeys::~ConfigureHotkeys() = default;
void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
for (const auto& group : registry.hotkey_groups) {
+ QString parent_item_data = QString::fromStdString(group.first);
auto* parent_item =
- new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(group.first)));
+ new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(parent_item_data)));
parent_item->setEditable(false);
- parent_item->setData(group.first);
+ parent_item->setData(parent_item_data);
for (const auto& hotkey : group.second) {
- auto* action =
- new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(hotkey.first)));
+ QString hotkey_action_data = QString::fromStdString(hotkey.first);
+ auto* action = new QStandardItem(
+ QCoreApplication::translate("Hotkeys", qPrintable(hotkey_action_data)));
auto* keyseq =
new QStandardItem(hotkey.second.keyseq.toString(QKeySequence::NativeText));
- auto* controller_keyseq = new QStandardItem(hotkey.second.controller_keyseq);
+ auto* controller_keyseq =
+ new QStandardItem(QString::fromStdString(hotkey.second.controller_keyseq));
action->setEditable(false);
- action->setData(hotkey.first);
+ action->setData(hotkey_action_data);
keyseq->setEditable(false);
controller_keyseq->setEditable(false);
parent_item->appendRow({action, keyseq, controller_keyseq});
@@ -301,13 +305,13 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
const QStandardItem* controller_keyseq =
parent->child(key_column_id, controller_column);
for (auto& [group, sub_actions] : registry.hotkey_groups) {
- if (group != parent->data())
+ if (group != parent->data().toString().toStdString())
continue;
for (auto& [action_name, hotkey] : sub_actions) {
- if (action_name != action->data())
+ if (action_name != action->data().toString().toStdString())
continue;
hotkey.keyseq = QKeySequence(keyseq->text());
- hotkey.controller_keyseq = controller_keyseq->text();
+ hotkey.controller_keyseq = controller_keyseq->text().toStdString();
}
}
}
@@ -319,7 +323,7 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
void ConfigureHotkeys::RestoreDefaults() {
for (int r = 0; r < model->rowCount(); ++r) {
const QStandardItem* parent = model->item(r, 0);
- const int hotkey_size = static_cast<int>(Config::default_hotkeys.size());
+ const int hotkey_size = static_cast<int>(UISettings::default_hotkeys.size());
if (hotkey_size != parent->rowCount()) {
QMessageBox::warning(this, tr("Invalid hotkey settings"),
@@ -330,10 +334,11 @@ void ConfigureHotkeys::RestoreDefaults() {
for (int r2 = 0; r2 < parent->rowCount(); ++r2) {
model->item(r, 0)
->child(r2, hotkey_column)
- ->setText(Config::default_hotkeys[r2].shortcut.keyseq);
+ ->setText(QString::fromStdString(UISettings::default_hotkeys[r2].shortcut.keyseq));
model->item(r, 0)
->child(r2, controller_column)
- ->setText(Config::default_hotkeys[r2].shortcut.controller_keyseq);
+ ->setText(QString::fromStdString(
+ UISettings::default_hotkeys[r2].shortcut.controller_keyseq));
}
}
}
@@ -379,7 +384,7 @@ void ConfigureHotkeys::PopupContextMenu(const QPoint& menu_location) {
void ConfigureHotkeys::RestoreControllerHotkey(QModelIndex index) {
const QString& default_key_sequence =
- Config::default_hotkeys[index.row()].shortcut.controller_keyseq;
+ QString::fromStdString(UISettings::default_hotkeys[index.row()].shortcut.controller_keyseq);
const auto [key_sequence_used, used_action] = IsUsedControllerKey(default_key_sequence);
if (key_sequence_used && default_key_sequence != model->data(index).toString()) {
@@ -393,7 +398,8 @@ void ConfigureHotkeys::RestoreControllerHotkey(QModelIndex index) {
void ConfigureHotkeys::RestoreHotkey(QModelIndex index) {
const QKeySequence& default_key_sequence = QKeySequence::fromString(
- Config::default_hotkeys[index.row()].shortcut.keyseq, QKeySequence::NativeText);
+ QString::fromStdString(UISettings::default_hotkeys[index.row()].shortcut.keyseq),
+ QKeySequence::NativeText);
const auto [key_sequence_used, used_action] = IsUsedKey(default_key_sequence);
if (key_sequence_used && default_key_sequence != QKeySequence(model->data(index).toString())) {
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 3dcad2701..02e23cce6 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -152,7 +152,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
connect(player_controllers[0], &ConfigureInputPlayer::HandheldStateChanged,
[this](bool is_handheld) { UpdateDockedState(is_handheld); });
- advanced = new ConfigureInputAdvanced(this);
+ advanced = new ConfigureInputAdvanced(hid_core, this);
ui->tabAdvanced->setLayout(new QHBoxLayout(ui->tabAdvanced));
ui->tabAdvanced->layout()->addWidget(advanced);
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h
index 136cd3a0a..beb503dae 100644
--- a/src/yuzu/configuration/configure_input.h
+++ b/src/yuzu/configuration/configure_input.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2016 Citra Emulator Project
+// SPDX-FileCopyrightText: 2016 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 3cfd5d439..441cea3f6 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -4,11 +4,13 @@
#include <QColorDialog>
#include "common/settings.h"
#include "core/core.h"
+#include "core/hid/emulated_controller.h"
+#include "core/hid/hid_core.h"
#include "ui_configure_input_advanced.h"
#include "yuzu/configuration/configure_input_advanced.h"
-ConfigureInputAdvanced::ConfigureInputAdvanced(QWidget* parent)
- : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputAdvanced>()) {
+ConfigureInputAdvanced::ConfigureInputAdvanced(Core::HID::HIDCore& hid_core_, QWidget* parent)
+ : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputAdvanced>()), hid_core{hid_core_} {
ui->setupUi(this);
controllers_color_buttons = {{
@@ -123,6 +125,8 @@ void ConfigureInputAdvanced::ApplyConfiguration() {
player.button_color_left = colors[1];
player.body_color_right = colors[2];
player.button_color_right = colors[3];
+
+ hid_core.GetEmulatedControllerByIndex(player_idx)->ReloadColorsFromSettings();
}
Settings::values.debug_pad_enabled = ui->debug_enabled->isChecked();
diff --git a/src/yuzu/configuration/configure_input_advanced.h b/src/yuzu/configuration/configure_input_advanced.h
index fc1230284..41f822c4a 100644
--- a/src/yuzu/configuration/configure_input_advanced.h
+++ b/src/yuzu/configuration/configure_input_advanced.h
@@ -14,11 +14,15 @@ namespace Ui {
class ConfigureInputAdvanced;
}
+namespace Core::HID {
+class HIDCore;
+} // namespace Core::HID
+
class ConfigureInputAdvanced : public QWidget {
Q_OBJECT
public:
- explicit ConfigureInputAdvanced(QWidget* parent = nullptr);
+ explicit ConfigureInputAdvanced(Core::HID::HIDCore& hid_core_, QWidget* parent = nullptr);
~ConfigureInputAdvanced() override;
void ApplyConfiguration();
@@ -44,4 +48,6 @@ private:
std::array<std::array<QColor, 4>, 8> controllers_colors;
std::array<std::array<QPushButton*, 4>, 8> controllers_color_buttons;
+
+ Core::HID::HIDCore& hid_core;
};
diff --git a/src/yuzu/configuration/configure_input_per_game.cpp b/src/yuzu/configuration/configure_input_per_game.cpp
index 78e65d468..8d9f65a05 100644
--- a/src/yuzu/configuration/configure_input_per_game.cpp
+++ b/src/yuzu/configuration/configure_input_per_game.cpp
@@ -5,12 +5,12 @@
#include "core/core.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
+#include "frontend_common/config.h"
#include "ui_configure_input_per_game.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_per_game.h"
#include "yuzu/configuration/input_profiles.h"
-ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, Config* config_,
+ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QtConfig* config_,
QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPerGame>()),
profiles(std::make_unique<InputProfiles>()), system{system_}, config{config_} {
@@ -110,6 +110,6 @@ void ConfigureInputPerGame::SaveConfiguration() {
// Clear all controls from the config in case the user reverted back to globals
config->ClearControlPlayerValues();
for (size_t index = 0; index < Settings::values.players.GetValue().size(); ++index) {
- config->SaveControlPlayerValue(index);
+ config->SaveQtControlPlayerValues(index);
}
}
diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h
index 660faf574..4420e856c 100644
--- a/src/yuzu/configuration/configure_input_per_game.h
+++ b/src/yuzu/configuration/configure_input_per_game.h
@@ -9,6 +9,7 @@
#include "ui_configure_input_per_game.h"
#include "yuzu/configuration/input_profiles.h"
+#include "yuzu/configuration/qt_config.h"
class QComboBox;
@@ -22,7 +23,7 @@ class ConfigureInputPerGame : public QWidget {
Q_OBJECT
public:
- explicit ConfigureInputPerGame(Core::System& system_, Config* config_,
+ explicit ConfigureInputPerGame(Core::System& system_, QtConfig* config_,
QWidget* parent = nullptr);
/// Load and Save configurations to settings file.
@@ -41,5 +42,5 @@ private:
std::array<QComboBox*, 8> profile_comboboxes;
Core::System& system;
- Config* config;
+ QtConfig* config;
};
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 576f5b571..0f7b3714e 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -12,15 +12,16 @@
#include <QTimer>
#include "common/assert.h"
#include "common/param_package.h"
+#include "configuration/qt_config.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hid/hid_types.h"
+#include "frontend_common/config.h"
#include "input_common/drivers/keyboard.h"
#include "input_common/drivers/mouse.h"
#include "input_common/main.h"
#include "ui_configure_input_player.h"
#include "yuzu/bootmanager.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_player.h"
#include "yuzu/configuration/configure_input_player_widget.h"
#include "yuzu/configuration/configure_mouse_panning.h"
@@ -322,11 +323,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
setFocusPolicy(Qt::ClickFocus);
button_map = {
- ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
- ui->buttonLStick, ui->buttonRStick, ui->buttonL, ui->buttonR,
- ui->buttonZL, ui->buttonZR, ui->buttonPlus, ui->buttonMinus,
- ui->buttonDpadLeft, ui->buttonDpadUp, ui->buttonDpadRight, ui->buttonDpadDown,
- ui->buttonSL, ui->buttonSR, ui->buttonHome, ui->buttonScreenshot,
+ ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
+ ui->buttonLStick, ui->buttonRStick, ui->buttonL, ui->buttonR,
+ ui->buttonZL, ui->buttonZR, ui->buttonPlus, ui->buttonMinus,
+ ui->buttonDpadLeft, ui->buttonDpadUp, ui->buttonDpadRight, ui->buttonDpadDown,
+ ui->buttonSLLeft, ui->buttonSRLeft, ui->buttonHome, ui->buttonScreenshot,
+ ui->buttonSLRight, ui->buttonSRRight,
};
analog_map_buttons = {{
@@ -1181,10 +1183,13 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() {
// List of all the widgets that will be hidden by any of the following layouts that need
// "unhidden" after the controller type changes
- const std::array<QWidget*, 11> layout_show = {
- ui->buttonShoulderButtonsSLSR,
+ const std::array<QWidget*, 14> layout_show = {
+ ui->buttonShoulderButtonsSLSRLeft,
+ ui->buttonShoulderButtonsSLSRRight,
ui->horizontalSpacerShoulderButtonsWidget,
ui->horizontalSpacerShoulderButtonsWidget2,
+ ui->horizontalSpacerShoulderButtonsWidget3,
+ ui->horizontalSpacerShoulderButtonsWidget4,
ui->buttonShoulderButtonsLeft,
ui->buttonMiscButtonsMinusScreenshot,
ui->bottomLeft,
@@ -1202,16 +1207,19 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() {
std::vector<QWidget*> layout_hidden;
switch (layout) {
case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::JoyconDual:
case Core::HID::NpadStyleIndex::Handheld:
layout_hidden = {
- ui->buttonShoulderButtonsSLSR,
+ ui->buttonShoulderButtonsSLSRLeft,
+ ui->buttonShoulderButtonsSLSRRight,
ui->horizontalSpacerShoulderButtonsWidget2,
+ ui->horizontalSpacerShoulderButtonsWidget4,
};
break;
case Core::HID::NpadStyleIndex::JoyconLeft:
layout_hidden = {
+ ui->buttonShoulderButtonsSLSRRight,
ui->horizontalSpacerShoulderButtonsWidget2,
+ ui->horizontalSpacerShoulderButtonsWidget3,
ui->buttonShoulderButtonsRight,
ui->buttonMiscButtonsPlusHome,
ui->bottomRight,
@@ -1219,16 +1227,17 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() {
break;
case Core::HID::NpadStyleIndex::JoyconRight:
layout_hidden = {
- ui->horizontalSpacerShoulderButtonsWidget,
- ui->buttonShoulderButtonsLeft,
- ui->buttonMiscButtonsMinusScreenshot,
- ui->bottomLeft,
+ ui->buttonShoulderButtonsSLSRLeft, ui->horizontalSpacerShoulderButtonsWidget,
+ ui->horizontalSpacerShoulderButtonsWidget4, ui->buttonShoulderButtonsLeft,
+ ui->buttonMiscButtonsMinusScreenshot, ui->bottomLeft,
};
break;
case Core::HID::NpadStyleIndex::GameCube:
layout_hidden = {
- ui->buttonShoulderButtonsSLSR,
+ ui->buttonShoulderButtonsSLSRLeft,
+ ui->buttonShoulderButtonsSLSRRight,
ui->horizontalSpacerShoulderButtonsWidget2,
+ ui->horizontalSpacerShoulderButtonsWidget4,
ui->buttonMiscButtonsMinusGroup,
ui->buttonMiscButtonsScreenshotGroup,
};
@@ -1389,25 +1398,25 @@ void ConfigureInputPlayer::UpdateMappingWithDefaults() {
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; ++button_id) {
emulated_controller->SetButtonParam(
button_id, Common::ParamPackage{InputCommon::GenerateKeyboardParam(
- Config::default_buttons[button_id])});
+ QtConfig::default_buttons[button_id])});
}
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
Common::ParamPackage analog_param{};
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
Common::ParamPackage params{InputCommon::GenerateKeyboardParam(
- Config::default_analogs[analog_id][sub_button_id])};
+ QtConfig::default_analogs[analog_id][sub_button_id])};
SetAnalogParam(params, analog_param, analog_sub_buttons[sub_button_id]);
}
analog_param.Set("modifier", InputCommon::GenerateKeyboardParam(
- Config::default_stick_mod[analog_id]));
+ QtConfig::default_stick_mod[analog_id]));
emulated_controller->SetStickParam(analog_id, analog_param);
}
for (int motion_id = 0; motion_id < Settings::NativeMotion::NumMotions; ++motion_id) {
emulated_controller->SetMotionParam(
motion_id, Common::ParamPackage{InputCommon::GenerateKeyboardParam(
- Config::default_motions[motion_id])});
+ QtConfig::default_motions[motion_id])});
}
// If mouse is selected we want to override with mappings from the driver
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index d3255d2b4..fda09e925 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2016 Citra Emulator Project
+// SPDX-FileCopyrightText: 2016 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
diff --git a/src/yuzu/configuration/configure_input_player.ui b/src/yuzu/configuration/configure_input_player.ui
index 611a79477..5518cccd1 100644
--- a/src/yuzu/configuration/configure_input_player.ui
+++ b/src/yuzu/configuration/configure_input_player.ui
@@ -1208,6 +1208,159 @@
<property name="spacing">
<number>3</number>
</property>
+ <item>
+ <widget class="QWidget" name="buttonShoulderButtonsSLSRLeft" native="true">
+ <layout class="QVBoxLayout" name="buttonShoulderButtonsSLSRLeftVerticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item alignment="Qt::AlignHCenter">
+ <widget class="QGroupBox" name="buttonShoulderButtonsSLLeftGroup">
+ <property name="title">
+ <string>SL</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <layout class="QVBoxLayout" name="buttonShoulderButtonsSLLeftVerticalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>3</number>
+ </property>
+ <property name="bottomMargin">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="buttonSLLeft">
+ <property name="minimumSize">
+ <size>
+ <width>68</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>68</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">min-width: 68px;</string>
+ </property>
+ <property name="text">
+ <string>SL</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item alignment="Qt::AlignHCenter">
+ <widget class="QGroupBox" name="buttonShoulderButtonsSRLeftGroup">
+ <property name="title">
+ <string>SR</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <layout class="QVBoxLayout" name="buttonShoulderButtonsSRLeftVerticalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>3</number>
+ </property>
+ <property name="bottomMargin">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="buttonSRLeft">
+ <property name="minimumSize">
+ <size>
+ <width>68</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>68</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">min-width: 68px;</string>
+ </property>
+ <property name="text">
+ <string>SR</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="horizontalSpacerShoulderButtonsWidget4" native="true">
+ <layout class="QHBoxLayout" name="horizontalSpacerShoulderButtonsWidget4Layout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacerShoulderButtons5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
<item>
<widget class="QWidget" name="buttonShoulderButtonsLeft" native="true">
<layout class="QVBoxLayout" name="buttonShoulderButtonsLeftVerticalLayout">
@@ -1830,125 +1983,125 @@
</layout>
</widget>
</item>
- <item>
- <widget class="QWidget" name="buttonShoulderButtonsSLSR" native="true">
- <layout class="QVBoxLayout" name="buttonShoulderButtonsSLSRVerticalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item alignment="Qt::AlignHCenter">
- <widget class="QGroupBox" name="buttonShoulderButtonsSLGroup">
- <property name="title">
- <string>SL</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <layout class="QVBoxLayout" name="buttonShoulderButtonsSLVerticalLayout">
- <property name="spacing">
- <number>3</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <widget class="QPushButton" name="buttonSL">
- <property name="minimumSize">
- <size>
- <width>68</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>68</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true">min-width: 68px;</string>
- </property>
- <property name="text">
- <string>SL</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item alignment="Qt::AlignHCenter">
- <widget class="QGroupBox" name="buttonShoulderButtonsSRGroup">
- <property name="title">
- <string>SR</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <layout class="QVBoxLayout" name="buttonShoulderButtonsSRVerticalLayout">
- <property name="spacing">
- <number>3</number>
- </property>
- <property name="leftMargin">
- <number>3</number>
- </property>
- <property name="topMargin">
- <number>3</number>
- </property>
- <property name="rightMargin">
- <number>3</number>
- </property>
- <property name="bottomMargin">
- <number>3</number>
- </property>
- <item>
- <widget class="QPushButton" name="buttonSR">
- <property name="minimumSize">
- <size>
- <width>68</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>68</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true">min-width: 68px;</string>
- </property>
- <property name="text">
- <string>SR</string>
- </property>
- </widget>
- </item>
+ <item>
+ <widget class="QWidget" name="buttonShoulderButtonsSLSRRight" native="true">
+ <layout class="QVBoxLayout" name="buttonShoulderButtonsSLSRRightVerticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item alignment="Qt::AlignHCenter">
+ <widget class="QGroupBox" name="buttonShoulderButtonsSLRightGroup">
+ <property name="title">
+ <string>SL</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <layout class="QVBoxLayout" name="buttonShoulderButtonsSLRightVerticalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>3</number>
+ </property>
+ <property name="bottomMargin">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="buttonSLRight">
+ <property name="minimumSize">
+ <size>
+ <width>68</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>68</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">min-width: 68px;</string>
+ </property>
+ <property name="text">
+ <string>SL</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item alignment="Qt::AlignHCenter">
+ <widget class="QGroupBox" name="buttonShoulderButtonsSRRightGroup">
+ <property name="title">
+ <string>SR</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <layout class="QVBoxLayout" name="buttonShoulderButtonsSRRightVerticalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>3</number>
+ </property>
+ <property name="bottomMargin">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="buttonSRRight">
+ <property name="minimumSize">
+ <size>
+ <width>68</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>68</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">min-width: 68px;</string>
+ </property>
+ <property name="text">
+ <string>SR</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
</layout>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
+ </widget>
+ </item>
</layout>
</item>
<item>
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp
index a188eef92..550cff9a0 100644
--- a/src/yuzu/configuration/configure_input_player_widget.cpp
+++ b/src/yuzu/configuration/configure_input_player_widget.cpp
@@ -297,8 +297,8 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center)
// Sideview SL and SR buttons
button_color = colors.slider_button;
- DrawRoundButton(p, center + QPoint(59, 52), button_values[SR], 5, 12, Direction::Left);
- DrawRoundButton(p, center + QPoint(59, -69), button_values[SL], 5, 12, Direction::Left);
+ DrawRoundButton(p, center + QPoint(59, 52), button_values[SRLeft], 5, 12, Direction::Left);
+ DrawRoundButton(p, center + QPoint(59, -69), button_values[SLLeft], 5, 12, Direction::Left);
DrawLeftBody(p, center);
@@ -353,8 +353,10 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center)
// SR and SL buttons
p.setPen(colors.outline);
button_color = colors.slider_button;
- DrawRoundButton(p, center + QPoint(155, 52), button_values[SR], 5.2f, 12, Direction::None, 4);
- DrawRoundButton(p, center + QPoint(155, -69), button_values[SL], 5.2f, 12, Direction::None, 4);
+ DrawRoundButton(p, center + QPoint(155, 52), button_values[SRLeft], 5.2f, 12, Direction::None,
+ 4);
+ DrawRoundButton(p, center + QPoint(155, -69), button_values[SLLeft], 5.2f, 12, Direction::None,
+ 4);
// SR and SL text
p.setPen(colors.transparent);
@@ -428,8 +430,10 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center
// Sideview SL and SR buttons
button_color = colors.slider_button;
- DrawRoundButton(p, center + QPoint(-59, 52), button_values[SL], 5, 11, Direction::Right);
- DrawRoundButton(p, center + QPoint(-59, -69), button_values[SR], 5, 11, Direction::Right);
+ DrawRoundButton(p, center + QPoint(-59, 52), button_values[SLRight], 5, 11,
+ Direction::Right);
+ DrawRoundButton(p, center + QPoint(-59, -69), button_values[SRRight], 5, 11,
+ Direction::Right);
DrawRightBody(p, center);
@@ -484,8 +488,10 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center
// SR and SL buttons
p.setPen(colors.outline);
button_color = colors.slider_button;
- DrawRoundButton(p, center + QPoint(-155, 52), button_values[SL], 5, 12, Direction::None, 4.0f);
- DrawRoundButton(p, center + QPoint(-155, -69), button_values[SR], 5, 12, Direction::None, 4.0f);
+ DrawRoundButton(p, center + QPoint(-155, 52), button_values[SLRight], 5, 12, Direction::None,
+ 4.0f);
+ DrawRoundButton(p, center + QPoint(-155, -69), button_values[SRRight], 5, 12, Direction::None,
+ 4.0f);
// SR and SL text
p.setPen(colors.transparent);
@@ -557,6 +563,19 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center)
DrawRoundButton(p, center + QPoint(-154, -72), button_values[Minus], 7, 4, Direction::Up,
1);
+ // Left SR and SL sideview buttons
+ button_color = colors.slider_button;
+ DrawRoundButton(p, center + QPoint(-20, -62), button_values[SLLeft], 4, 11,
+ Direction::Left);
+ DrawRoundButton(p, center + QPoint(-20, 47), button_values[SRLeft], 4, 11, Direction::Left);
+
+ // Right SR and SL sideview buttons
+ button_color = colors.slider_button;
+ DrawRoundButton(p, center + QPoint(20, 47), button_values[SLRight], 4, 11,
+ Direction::Right);
+ DrawRoundButton(p, center + QPoint(20, -62), button_values[SRRight], 4, 11,
+ Direction::Right);
+
DrawDualBody(p, center);
// Right trigger top view
@@ -1792,16 +1811,6 @@ void PlayerControlPreview::DrawDualBody(QPainter& p, const QPointF center) {
p.setBrush(colors.right);
DrawPolygon(p, qright_joycon_topview);
- // Right SR and SL sideview buttons
- p.setPen(colors.outline);
- p.setBrush(colors.slider_button);
- DrawRoundRectangle(p, center + QPoint(19, 47), 7, 22, 1);
- DrawRoundRectangle(p, center + QPoint(19, -62), 7, 22, 1);
-
- // Left SR and SL sideview buttons
- DrawRoundRectangle(p, center + QPoint(-19, 47), 7, 22, 1);
- DrawRoundRectangle(p, center + QPoint(-19, -62), 7, 22, 1);
-
// Right Sideview body
p.setBrush(colors.slider);
DrawPolygon(p, qright_joycon_slider);
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index b91d6ad4a..b274a3321 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -25,8 +25,8 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/xts_archive.h"
#include "core/loader/loader.h"
+#include "frontend_common/config.h"
#include "ui_configure_per_game.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_audio.h"
#include "yuzu/configuration/configure_cpu.h"
@@ -50,8 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name));
const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename())
: fmt::format("{:016X}", title_id);
- game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
-
+ game_config = std::make_unique<QtConfig>(config_file_name, Config::ConfigType::PerGameConfig);
addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this);
audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, *builder, this);
cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, *builder, this);
@@ -108,7 +107,7 @@ void ConfigurePerGame::ApplyConfiguration() {
system.ApplySettings();
Settings::LogSettings();
- game_config->Save();
+ game_config->SaveAllValues();
}
void ConfigurePerGame::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h
index 1a727f32c..c8ee46c04 100644
--- a/src/yuzu/configuration/configure_per_game.h
+++ b/src/yuzu/configuration/configure_per_game.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -12,9 +12,10 @@
#include "configuration/shared_widget.h"
#include "core/file_sys/vfs_types.h"
+#include "frontend_common/config.h"
#include "vk_device_info.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configuration_shared.h"
+#include "yuzu/configuration/qt_config.h"
#include "yuzu/configuration/shared_translation.h"
namespace Core {
@@ -72,7 +73,7 @@ private:
QGraphicsScene* scene;
- std::unique_ptr<Config> game_config;
+ std::unique_ptr<QtConfig> game_config;
Core::System& system;
std::unique_ptr<ConfigurationShared::Builder> builder;
diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp
index 674a75a62..140a7fe5d 100644
--- a/src/yuzu/configuration/configure_per_game_addons.cpp
+++ b/src/yuzu/configuration/configure_per_game_addons.cpp
@@ -19,7 +19,6 @@
#include "core/file_sys/xts_archive.h"
#include "core/loader/loader.h"
#include "ui_configure_per_game_addons.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input.h"
#include "yuzu/configuration/configure_per_game_addons.h"
#include "yuzu/uisettings.h"
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index a47089988..6d2219bf5 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -306,10 +306,10 @@ void ConfigureProfileManager::SetUserImage() {
return;
}
- // Some games crash when the profile image is too big. Resize any image bigger than 256x256
+ // Profile image must be 256x256
QImage image(image_path);
- if (image.width() > 256 || image.height() > 256) {
- image = image.scaled(256, 256, Qt::KeepAspectRatio);
+ if (image.width() != 256 || image.height() != 256) {
+ image = image.scaled(256, 256, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
if (!image.save(image_path)) {
QMessageBox::warning(this, tr("Error resizing user image"),
tr("Unable to resize image"));
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp
index f83705544..9572ff43c 100644
--- a/src/yuzu/configuration/configure_ringcon.cpp
+++ b/src/yuzu/configuration/configure_ringcon.cpp
@@ -8,6 +8,7 @@
#include <QTimer>
#include <fmt/format.h>
+#include "configuration/qt_config.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "input_common/drivers/keyboard.h"
@@ -15,7 +16,6 @@
#include "input_common/main.h"
#include "ui_configure_ringcon.h"
#include "yuzu/bootmanager.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_ringcon.h"
const std::array<std::string, ConfigureRingController::ANALOG_SUB_BUTTONS_NUM>
@@ -270,7 +270,7 @@ void ConfigureRingController::LoadConfiguration() {
void ConfigureRingController::RestoreDefaults() {
const std::string default_ring_string = InputCommon::GenerateAnalogParamFromKeys(
- 0, 0, Config::default_ringcon_analogs[0], Config::default_ringcon_analogs[1], 0, 0.05f);
+ 0, 0, QtConfig::default_ringcon_analogs[0], QtConfig::default_ringcon_analogs[1], 0, 0.05f);
emulated_controller->SetRingParam(Common::ParamPackage(default_ring_string));
UpdateUI();
}
diff --git a/src/yuzu/configuration/configure_ringcon.h b/src/yuzu/configuration/configure_ringcon.h
index b23c27906..6fd95e2b8 100644
--- a/src/yuzu/configuration/configure_ringcon.h
+++ b/src/yuzu/configuration/configure_ringcon.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 0c8e5c8b4..7cbf43775 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -16,7 +16,6 @@
#include "core/core.h"
#include "core/hle/service/time/time_manager.h"
#include "ui_configure_system.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_system.h"
#include "yuzu/configuration/shared_widget.h"
diff --git a/src/yuzu/configuration/configure_tas.h b/src/yuzu/configuration/configure_tas.h
index 4a6b0ba4e..a91891906 100644
--- a/src/yuzu/configuration/configure_tas.h
+++ b/src/yuzu/configuration/configure_tas.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.cpp b/src/yuzu/configuration/configure_touchscreen_advanced.cpp
index 5a03e48df..94df6d9d3 100644
--- a/src/yuzu/configuration/configure_touchscreen_advanced.cpp
+++ b/src/yuzu/configuration/configure_touchscreen_advanced.cpp
@@ -2,8 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <memory>
+#include "common/settings.h"
#include "ui_configure_touchscreen_advanced.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_touchscreen_advanced.h"
ConfigureTouchscreenAdvanced::ConfigureTouchscreenAdvanced(QWidget* parent)
diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.h b/src/yuzu/configuration/configure_touchscreen_advanced.h
index 034dc0d46..b6fdffdc8 100644
--- a/src/yuzu/configuration/configure_touchscreen_advanced.h
+++ b/src/yuzu/configuration/configure_touchscreen_advanced.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2016 Citra Emulator Project
+// SPDX-FileCopyrightText: 2016 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index 82f3b6e78..dd43f0a0e 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -164,7 +164,7 @@ ConfigureUi::~ConfigureUi() = default;
void ConfigureUi::ApplyConfiguration() {
UISettings::values.theme =
- ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
+ ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString().toStdString();
UISettings::values.show_add_ons = ui->show_add_ons->isChecked();
UISettings::values.show_compat = ui->show_compat->isChecked();
UISettings::values.show_size = ui->show_size->isChecked();
@@ -191,9 +191,10 @@ void ConfigureUi::RequestGameListUpdate() {
}
void ConfigureUi::SetConfiguration() {
- ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
+ ui->theme_combobox->setCurrentIndex(
+ ui->theme_combobox->findData(QString::fromStdString(UISettings::values.theme)));
ui->language_combobox->setCurrentIndex(
- ui->language_combobox->findData(UISettings::values.language));
+ ui->language_combobox->findData(QString::fromStdString(UISettings::values.language)));
ui->show_add_ons->setChecked(UISettings::values.show_add_ons.GetValue());
ui->show_compat->setChecked(UISettings::values.show_compat.GetValue());
ui->show_size->setChecked(UISettings::values.show_size.GetValue());
diff --git a/src/yuzu/configuration/input_profiles.cpp b/src/yuzu/configuration/input_profiles.cpp
index 41ef4250a..716efbccd 100644
--- a/src/yuzu/configuration/input_profiles.cpp
+++ b/src/yuzu/configuration/input_profiles.cpp
@@ -5,7 +5,7 @@
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
-#include "yuzu/configuration/config.h"
+#include "frontend_common/config.h"
#include "yuzu/configuration/input_profiles.h"
namespace FS = Common::FS;
@@ -44,7 +44,7 @@ InputProfiles::InputProfiles() {
if (IsINI(filename) && IsProfileNameValid(name_without_ext)) {
map_profiles.insert_or_assign(
name_without_ext,
- std::make_unique<Config>(name_without_ext, Config::ConfigType::InputProfile));
+ std::make_unique<QtConfig>(name_without_ext, Config::ConfigType::InputProfile));
}
return true;
@@ -85,7 +85,7 @@ bool InputProfiles::CreateProfile(const std::string& profile_name, std::size_t p
}
map_profiles.insert_or_assign(
- profile_name, std::make_unique<Config>(profile_name, Config::ConfigType::InputProfile));
+ profile_name, std::make_unique<QtConfig>(profile_name, Config::ConfigType::InputProfile));
return SaveProfile(profile_name, player_index);
}
@@ -113,7 +113,7 @@ bool InputProfiles::LoadProfile(const std::string& profile_name, std::size_t pla
return false;
}
- map_profiles[profile_name]->ReadControlPlayerValue(player_index);
+ map_profiles[profile_name]->ReadQtControlPlayerValues(player_index);
return true;
}
@@ -122,7 +122,7 @@ bool InputProfiles::SaveProfile(const std::string& profile_name, std::size_t pla
return false;
}
- map_profiles[profile_name]->SaveControlPlayerValue(player_index);
+ map_profiles[profile_name]->SaveQtControlPlayerValues(player_index);
return true;
}
diff --git a/src/yuzu/configuration/input_profiles.h b/src/yuzu/configuration/input_profiles.h
index 2bf3e4250..023ec74a6 100644
--- a/src/yuzu/configuration/input_profiles.h
+++ b/src/yuzu/configuration/input_profiles.h
@@ -6,6 +6,8 @@
#include <string>
#include <unordered_map>
+#include "configuration/qt_config.h"
+
namespace Core {
class System;
}
@@ -30,5 +32,5 @@ public:
private:
bool ProfileExistsInMap(const std::string& profile_name) const;
- std::unordered_map<std::string, std::unique_ptr<Config>> map_profiles;
+ std::unordered_map<std::string, std::unique_ptr<QtConfig>> map_profiles;
};
diff --git a/src/yuzu/configuration/qt_config.cpp b/src/yuzu/configuration/qt_config.cpp
new file mode 100644
index 000000000..5a8e69aa9
--- /dev/null
+++ b/src/yuzu/configuration/qt_config.cpp
@@ -0,0 +1,549 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "input_common/main.h"
+#include "qt_config.h"
+#include "uisettings.h"
+
+const std::array<int, Settings::NativeButton::NumButtons> QtConfig::default_buttons = {
+ Qt::Key_C, Qt::Key_X, Qt::Key_V, Qt::Key_Z, Qt::Key_F,
+ Qt::Key_G, Qt::Key_Q, Qt::Key_E, Qt::Key_R, Qt::Key_T,
+ Qt::Key_M, Qt::Key_N, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right,
+ Qt::Key_Down, Qt::Key_Q, Qt::Key_E, 0, 0,
+ Qt::Key_Q, Qt::Key_E,
+};
+
+const std::array<int, Settings::NativeMotion::NumMotions> QtConfig::default_motions = {
+ Qt::Key_7,
+ Qt::Key_8,
+};
+
+const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> QtConfig::default_analogs{{
+ {
+ Qt::Key_W,
+ Qt::Key_S,
+ Qt::Key_A,
+ Qt::Key_D,
+ },
+ {
+ Qt::Key_I,
+ Qt::Key_K,
+ Qt::Key_J,
+ Qt::Key_L,
+ },
+}};
+
+const std::array<int, 2> QtConfig::default_stick_mod = {
+ Qt::Key_Shift,
+ 0,
+};
+
+const std::array<int, 2> QtConfig::default_ringcon_analogs{{
+ Qt::Key_A,
+ Qt::Key_D,
+}};
+
+QtConfig::QtConfig(const std::string& config_name, const ConfigType config_type)
+ : Config(config_type) {
+ Initialize(config_name);
+ if (config_type != ConfigType::InputProfile) {
+ ReadQtValues();
+ SaveQtValues();
+ }
+}
+
+QtConfig::~QtConfig() {
+ if (global) {
+ QtConfig::SaveAllValues();
+ }
+}
+
+void QtConfig::ReloadAllValues() {
+ Reload();
+ ReadQtValues();
+ SaveQtValues();
+}
+
+void QtConfig::SaveAllValues() {
+ Save();
+ SaveQtValues();
+}
+
+void QtConfig::ReadQtValues() {
+ if (global) {
+ ReadUIValues();
+ }
+ ReadQtControlValues();
+}
+
+void QtConfig::ReadQtPlayerValues(const std::size_t player_index) {
+ std::string player_prefix;
+ if (type != ConfigType::InputProfile) {
+ player_prefix.append("player_").append(ToString(player_index)).append("_");
+ }
+
+ auto& player = Settings::values.players.GetValue()[player_index];
+ if (IsCustomConfig()) {
+ const auto profile_name =
+ ReadStringSetting(std::string(player_prefix).append("profile_name"));
+ if (profile_name.empty()) {
+ // Use the global input config
+ player = Settings::values.players.GetValue(true)[player_index];
+ return;
+ }
+ }
+
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ auto& player_buttons = player.buttons[i];
+
+ player_buttons = ReadStringSetting(
+ std::string(player_prefix).append(Settings::NativeButton::mapping[i]), default_param);
+ if (player_buttons.empty()) {
+ player_buttons = default_param;
+ }
+ }
+
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ auto& player_analogs = player.analogs[i];
+
+ player_analogs = ReadStringSetting(
+ std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]), default_param);
+ if (player_analogs.empty()) {
+ player_analogs = default_param;
+ }
+ }
+
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ auto& player_motions = player.motions[i];
+
+ player_motions = ReadStringSetting(
+ std::string(player_prefix).append(Settings::NativeMotion::mapping[i]), default_param);
+ if (player_motions.empty()) {
+ player_motions = default_param;
+ }
+ }
+}
+
+void QtConfig::ReadHidbusValues() {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ 0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
+ auto& ringcon_analogs = Settings::values.ringcon_analogs;
+
+ ringcon_analogs = ReadStringSetting(std::string("ring_controller"), default_param);
+ if (ringcon_analogs.empty()) {
+ ringcon_analogs = default_param;
+ }
+}
+
+void QtConfig::ReadDebugControlValues() {
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ auto& debug_pad_buttons = Settings::values.debug_pad_buttons[i];
+
+ debug_pad_buttons = ReadStringSetting(
+ std::string("debug_pad_").append(Settings::NativeButton::mapping[i]), default_param);
+ if (debug_pad_buttons.empty()) {
+ debug_pad_buttons = default_param;
+ }
+ }
+
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ auto& debug_pad_analogs = Settings::values.debug_pad_analogs[i];
+
+ debug_pad_analogs = ReadStringSetting(
+ std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]), default_param);
+ if (debug_pad_analogs.empty()) {
+ debug_pad_analogs = default_param;
+ }
+ }
+}
+
+void QtConfig::ReadQtControlValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ Settings::values.players.SetGlobal(!IsCustomConfig());
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
+ ReadQtPlayerValues(p);
+ }
+ if (IsCustomConfig()) {
+ EndGroup();
+ return;
+ }
+ ReadDebugControlValues();
+ ReadHidbusValues();
+
+ EndGroup();
+}
+
+void QtConfig::ReadPathValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Paths));
+
+ UISettings::values.roms_path = ReadStringSetting(std::string("romsPath"));
+ UISettings::values.symbols_path = ReadStringSetting(std::string("symbolsPath"));
+ UISettings::values.game_dir_deprecated =
+ ReadStringSetting(std::string("gameListRootDir"), std::string("."));
+ UISettings::values.game_dir_deprecated_deepscan =
+ ReadBooleanSetting(std::string("gameListDeepScan"), std::make_optional(false));
+
+ const int gamedirs_size = BeginArray(std::string("gamedirs"));
+ for (int i = 0; i < gamedirs_size; ++i) {
+ SetArrayIndex(i);
+ UISettings::GameDir game_dir;
+ game_dir.path = ReadStringSetting(std::string("path"));
+ game_dir.deep_scan =
+ ReadBooleanSetting(std::string("deep_scan"), std::make_optional(false));
+ game_dir.expanded = ReadBooleanSetting(std::string("expanded"), std::make_optional(true));
+ UISettings::values.game_dirs.append(game_dir);
+ }
+ EndArray();
+
+ // Create NAND and SD card directories if empty, these are not removable through the UI,
+ // also carries over old game list settings if present
+ if (UISettings::values.game_dirs.empty()) {
+ UISettings::GameDir game_dir;
+ game_dir.path = std::string("SDMC");
+ game_dir.expanded = true;
+ UISettings::values.game_dirs.append(game_dir);
+ game_dir.path = std::string("UserNAND");
+ UISettings::values.game_dirs.append(game_dir);
+ game_dir.path = std::string("SysNAND");
+ UISettings::values.game_dirs.append(game_dir);
+ if (UISettings::values.game_dir_deprecated != std::string(".")) {
+ game_dir.path = UISettings::values.game_dir_deprecated;
+ game_dir.deep_scan = UISettings::values.game_dir_deprecated_deepscan;
+ UISettings::values.game_dirs.append(game_dir);
+ }
+ }
+ UISettings::values.recent_files =
+ QString::fromStdString(ReadStringSetting(std::string("recentFiles")))
+ .split(QStringLiteral(", "), Qt::SkipEmptyParts, Qt::CaseSensitive);
+ UISettings::values.language = ReadStringSetting(std::string("language"), std::string(""));
+
+ EndGroup();
+}
+
+void QtConfig::ReadShortcutValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Shortcuts));
+
+ for (const auto& [name, group, shortcut] : UISettings::default_hotkeys) {
+ BeginGroup(group);
+ BeginGroup(name);
+
+ // No longer using ReadSetting for shortcut.second as it inaccurately returns a value of 1
+ // for WidgetWithChildrenShortcut which is a value of 3. Needed to fix shortcuts the open
+ // a file dialog in windowed mode
+ UISettings::values.shortcuts.push_back(
+ {name,
+ group,
+ {ReadStringSetting(std::string("KeySeq"), shortcut.keyseq),
+ ReadStringSetting(std::string("Controller_KeySeq"), shortcut.controller_keyseq),
+ shortcut.context,
+ ReadBooleanSetting(std::string("Repeat"), std::optional(shortcut.repeat))}});
+
+ EndGroup(); // name
+ EndGroup(); // group
+ }
+
+ EndGroup();
+}
+
+void QtConfig::ReadUIValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Ui));
+
+ UISettings::values.theme = ReadStringSetting(
+ std::string("theme"),
+ std::string(UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second));
+
+ ReadUIGamelistValues();
+ ReadUILayoutValues();
+ ReadPathValues();
+ ReadScreenshotValues();
+ ReadShortcutValues();
+ ReadMultiplayerValues();
+
+ ReadCategory(Settings::Category::Ui);
+ ReadCategory(Settings::Category::UiGeneral);
+
+ EndGroup();
+}
+
+void QtConfig::ReadUIGamelistValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList));
+
+ ReadCategory(Settings::Category::UiGameList);
+
+ const int favorites_size = BeginArray("favorites");
+ for (int i = 0; i < favorites_size; i++) {
+ SetArrayIndex(i);
+ UISettings::values.favorited_ids.append(
+ ReadUnsignedIntegerSetting(std::string("program_id")));
+ }
+ EndArray();
+
+ EndGroup();
+}
+
+void QtConfig::ReadUILayoutValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList));
+
+ ReadCategory(Settings::Category::UiLayout);
+
+ EndGroup();
+}
+
+void QtConfig::ReadMultiplayerValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Multiplayer));
+
+ ReadCategory(Settings::Category::Multiplayer);
+
+ // Read ban list back
+ int size = BeginArray(std::string("username_ban_list"));
+ UISettings::values.multiplayer_ban_list.first.resize(size);
+ for (int i = 0; i < size; ++i) {
+ SetArrayIndex(i);
+ UISettings::values.multiplayer_ban_list.first[i] =
+ ReadStringSetting(std::string("username"), std::string(""));
+ }
+ EndArray();
+
+ size = BeginArray(std::string("ip_ban_list"));
+ UISettings::values.multiplayer_ban_list.second.resize(size);
+ for (int i = 0; i < size; ++i) {
+ UISettings::values.multiplayer_ban_list.second[i] =
+ ReadStringSetting("username", std::string(""));
+ }
+ EndArray();
+
+ EndGroup();
+}
+
+void QtConfig::SaveQtValues() {
+ if (global) {
+ SaveUIValues();
+ }
+ SaveQtControlValues();
+
+ WriteToIni();
+}
+
+void QtConfig::SaveQtPlayerValues(const std::size_t player_index) {
+ std::string player_prefix;
+ if (type != ConfigType::InputProfile) {
+ player_prefix = std::string("player_").append(ToString(player_index)).append("_");
+ }
+
+ const auto& player = Settings::values.players.GetValue()[player_index];
+ if (IsCustomConfig() && player.profile_name.empty()) {
+ // No custom profile selected
+ return;
+ }
+
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ WriteSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]),
+ player.buttons[i], std::make_optional(default_param));
+ }
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ WriteSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]),
+ player.analogs[i], std::make_optional(default_param));
+ }
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ WriteSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]),
+ player.motions[i], std::make_optional(default_param));
+ }
+}
+
+void QtConfig::SaveDebugControlValues() {
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ WriteSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]),
+ Settings::values.debug_pad_buttons[i], std::make_optional(default_param));
+ }
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ WriteSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]),
+ Settings::values.debug_pad_analogs[i], std::make_optional(default_param));
+ }
+}
+
+void QtConfig::SaveHidbusValues() {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ 0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
+ WriteSetting(std::string("ring_controller"), Settings::values.ringcon_analogs,
+ std::make_optional(default_param));
+}
+
+void QtConfig::SaveQtControlValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ Settings::values.players.SetGlobal(!IsCustomConfig());
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
+ SaveQtPlayerValues(p);
+ }
+ if (IsCustomConfig()) {
+ EndGroup();
+ return;
+ }
+ SaveDebugControlValues();
+ SaveHidbusValues();
+
+ EndGroup();
+}
+
+void QtConfig::SavePathValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Paths));
+
+ WriteSetting(std::string("romsPath"), UISettings::values.roms_path);
+ WriteSetting(std::string("symbolsPath"), UISettings::values.symbols_path);
+ BeginArray(std::string("gamedirs"));
+ for (int i = 0; i < UISettings::values.game_dirs.size(); ++i) {
+ SetArrayIndex(i);
+ const auto& game_dir = UISettings::values.game_dirs[i];
+ WriteSetting(std::string("path"), game_dir.path);
+ WriteSetting(std::string("deep_scan"), game_dir.deep_scan, std::make_optional(false));
+ WriteSetting(std::string("expanded"), game_dir.expanded, std::make_optional(true));
+ }
+ EndArray();
+
+ WriteSetting(std::string("recentFiles"),
+ UISettings::values.recent_files.join(QStringLiteral(", ")).toStdString());
+ WriteSetting(std::string("language"), UISettings::values.language);
+
+ EndGroup();
+}
+
+void QtConfig::SaveShortcutValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Shortcuts));
+
+ // Lengths of UISettings::values.shortcuts & default_hotkeys are same.
+ // However, their ordering must also be the same.
+ for (std::size_t i = 0; i < UISettings::default_hotkeys.size(); i++) {
+ const auto& [name, group, shortcut] = UISettings::values.shortcuts[i];
+ const auto& default_hotkey = UISettings::default_hotkeys[i].shortcut;
+
+ BeginGroup(group);
+ BeginGroup(name);
+
+ WriteSetting(std::string("KeySeq"), shortcut.keyseq,
+ std::make_optional(default_hotkey.keyseq));
+ WriteSetting(std::string("Controller_KeySeq"), shortcut.controller_keyseq,
+ std::make_optional(default_hotkey.controller_keyseq));
+ WriteSetting(std::string("Context"), shortcut.context,
+ std::make_optional(default_hotkey.context));
+ WriteSetting(std::string("Repeat"), shortcut.repeat,
+ std::make_optional(default_hotkey.repeat));
+
+ EndGroup(); // name
+ EndGroup(); // group
+ }
+
+ EndGroup();
+}
+
+void QtConfig::SaveUIValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Ui));
+
+ WriteCategory(Settings::Category::Ui);
+ WriteCategory(Settings::Category::UiGeneral);
+
+ WriteSetting(std::string("theme"), UISettings::values.theme,
+ std::make_optional(std::string(
+ UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second)));
+
+ SaveUIGamelistValues();
+ SaveUILayoutValues();
+ SavePathValues();
+ SaveScreenshotValues();
+ SaveShortcutValues();
+ SaveMultiplayerValues();
+
+ EndGroup();
+}
+
+void QtConfig::SaveUIGamelistValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList));
+
+ WriteCategory(Settings::Category::UiGameList);
+
+ BeginArray(std::string("favorites"));
+ for (int i = 0; i < UISettings::values.favorited_ids.size(); i++) {
+ SetArrayIndex(i);
+ WriteSetting(std::string("program_id"), UISettings::values.favorited_ids[i]);
+ }
+ EndArray(); // favorites
+
+ EndGroup();
+}
+
+void QtConfig::SaveUILayoutValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::UiLayout));
+
+ WriteCategory(Settings::Category::UiLayout);
+
+ EndGroup();
+}
+
+void QtConfig::SaveMultiplayerValues() {
+ BeginGroup(std::string("Multiplayer"));
+
+ WriteCategory(Settings::Category::Multiplayer);
+
+ // Write ban list
+ BeginArray(std::string("username_ban_list"));
+ for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.first.size(); ++i) {
+ SetArrayIndex(static_cast<int>(i));
+ WriteSetting(std::string("username"), UISettings::values.multiplayer_ban_list.first[i]);
+ }
+ EndArray(); // username_ban_list
+
+ BeginArray(std::string("ip_ban_list"));
+ for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.second.size(); ++i) {
+ SetArrayIndex(static_cast<int>(i));
+ WriteSetting(std::string("ip"), UISettings::values.multiplayer_ban_list.second[i]);
+ }
+ EndArray(); // ip_ban_list
+
+ EndGroup();
+}
+
+std::vector<Settings::BasicSetting*>& QtConfig::FindRelevantList(Settings::Category category) {
+ auto& map = Settings::values.linkage.by_category;
+ if (map.contains(category)) {
+ return Settings::values.linkage.by_category[category];
+ }
+ return UISettings::values.linkage.by_category[category];
+}
+
+void QtConfig::ReadQtControlPlayerValues(std::size_t player_index) {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ ReadPlayerValues(player_index);
+ ReadQtPlayerValues(player_index);
+
+ EndGroup();
+}
+
+void QtConfig::SaveQtControlPlayerValues(std::size_t player_index) {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ SavePlayerValues(player_index);
+ SaveQtPlayerValues(player_index);
+
+ EndGroup();
+
+ WriteToIni();
+}
diff --git a/src/yuzu/configuration/qt_config.h b/src/yuzu/configuration/qt_config.h
new file mode 100644
index 000000000..dc2dceb4d
--- /dev/null
+++ b/src/yuzu/configuration/qt_config.h
@@ -0,0 +1,55 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <QMetaType>
+
+#include "frontend_common/config.h"
+
+class QtConfig final : public Config {
+public:
+ explicit QtConfig(const std::string& config_name = "qt-config",
+ ConfigType config_type = ConfigType::GlobalConfig);
+ ~QtConfig() override;
+
+ void ReloadAllValues() override;
+ void SaveAllValues() override;
+
+ void ReadQtControlPlayerValues(std::size_t player_index);
+ void SaveQtControlPlayerValues(std::size_t player_index);
+
+protected:
+ void ReadQtValues();
+ void ReadQtPlayerValues(std::size_t player_index);
+ void ReadQtControlValues();
+ void ReadHidbusValues() override;
+ void ReadDebugControlValues() override;
+ void ReadPathValues() override;
+ void ReadShortcutValues() override;
+ void ReadUIValues() override;
+ void ReadUIGamelistValues() override;
+ void ReadUILayoutValues() override;
+ void ReadMultiplayerValues() override;
+
+ void SaveQtValues();
+ void SaveQtPlayerValues(std::size_t player_index);
+ void SaveQtControlValues();
+ void SaveHidbusValues() override;
+ void SaveDebugControlValues() override;
+ void SavePathValues() override;
+ void SaveShortcutValues() override;
+ void SaveUIValues() override;
+ void SaveUIGamelistValues() override;
+ void SaveUILayoutValues() override;
+ void SaveMultiplayerValues() override;
+
+ std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override;
+
+public:
+ static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
+ static const std::array<int, Settings::NativeMotion::NumMotions> default_motions;
+ static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs;
+ static const std::array<int, 2> default_stick_mod;
+ static const std::array<int, 2> default_ringcon_analogs;
+};
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index 3fe448f27..a7b5def32 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -1,17 +1,18 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include "common/time_zone.h"
#include "yuzu/configuration/shared_translation.h"
#include <map>
#include <memory>
#include <tuple>
#include <utility>
+#include <QCoreApplication>
#include <QWidget>
#include "common/settings.h"
#include "common/settings_enums.h"
#include "common/settings_setting.h"
+#include "common/time_zone.h"
#include "yuzu/uisettings.h"
namespace ConfigurationShared {
@@ -21,123 +22,135 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); };
#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \
- translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{tr((NAME)), tr((TOOLTIP))}})
+ translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{(NAME), (TOOLTIP)}})
// A setting can be ignored by giving it a blank name
// Audio
- INSERT(Settings, sink_id, "Output Engine:", "");
- INSERT(Settings, audio_output_device_id, "Output Device:", "");
- INSERT(Settings, audio_input_device_id, "Input Device:", "");
- INSERT(Settings, audio_muted, "Mute audio", "");
- INSERT(Settings, volume, "Volume:", "");
- INSERT(Settings, dump_audio_commands, "", "");
- INSERT(UISettings, mute_when_in_background, "Mute audio when in background", "");
+ INSERT(Settings, sink_id, tr("Output Engine:"), QStringLiteral());
+ INSERT(Settings, audio_output_device_id, tr("Output Device:"), QStringLiteral());
+ INSERT(Settings, audio_input_device_id, tr("Input Device:"), QStringLiteral());
+ INSERT(Settings, audio_muted, tr("Mute audio"), QStringLiteral());
+ INSERT(Settings, volume, tr("Volume:"), QStringLiteral());
+ INSERT(Settings, dump_audio_commands, QStringLiteral(), QStringLiteral());
+ INSERT(UISettings, mute_when_in_background, tr("Mute audio when in background"),
+ QStringLiteral());
// Core
- INSERT(Settings, use_multi_core, "Multicore CPU Emulation", "");
- INSERT(Settings, memory_layout_mode, "Memory Layout", "");
- INSERT(Settings, use_speed_limit, "", "");
- INSERT(Settings, speed_limit, "Limit Speed Percent", "");
+ INSERT(Settings, use_multi_core, tr("Multicore CPU Emulation"), QStringLiteral());
+ INSERT(Settings, memory_layout_mode, tr("Memory Layout"), QStringLiteral());
+ INSERT(Settings, use_speed_limit, QStringLiteral(), QStringLiteral());
+ INSERT(Settings, speed_limit, tr("Limit Speed Percent"), QStringLiteral());
// Cpu
- INSERT(Settings, cpu_accuracy, "Accuracy:", "");
+ INSERT(Settings, cpu_accuracy, tr("Accuracy:"), QStringLiteral());
// Cpu Debug
// Cpu Unsafe
- INSERT(Settings, cpuopt_unsafe_unfuse_fma,
- "Unfuse FMA (improve performance on CPUs without FMA)",
- "This option improves speed by reducing accuracy of fused-multiply-add instructions on "
- "CPUs without native FMA support.");
- INSERT(Settings, cpuopt_unsafe_reduce_fp_error, "Faster FRSQRTE and FRECPE",
- "This option improves the speed of some approximate floating-point functions by using "
- "less accurate native approximations.");
- INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr, "Faster ASIMD instructions (32 bits only)",
- "This option improves the speed of 32 bits ASIMD floating-point functions by running "
- "with incorrect rounding modes.");
- INSERT(Settings, cpuopt_unsafe_inaccurate_nan, "Inaccurate NaN handling",
- "This option improves speed by removing NaN checking. Please note this also reduces "
- "accuracy of certain floating-point instructions.");
INSERT(
- Settings, cpuopt_unsafe_fastmem_check, "Disable address space checks",
- "This option improves speed by eliminating a safety check before every memory read/write "
- "in guest. Disabling it may allow a game to read/write the emulator's memory.");
- INSERT(Settings, cpuopt_unsafe_ignore_global_monitor, "Ignore global monitor",
- "This option improves speed by relying only on the semantics of cmpxchg to ensure "
+ Settings, cpuopt_unsafe_unfuse_fma,
+ tr("Unfuse FMA (improve performance on CPUs without FMA)"),
+ tr("This option improves speed by reducing accuracy of fused-multiply-add instructions on "
+ "CPUs without native FMA support."));
+ INSERT(
+ Settings, cpuopt_unsafe_reduce_fp_error, tr("Faster FRSQRTE and FRECPE"),
+ tr("This option improves the speed of some approximate floating-point functions by using "
+ "less accurate native approximations."));
+ INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr,
+ tr("Faster ASIMD instructions (32 bits only)"),
+ tr("This option improves the speed of 32 bits ASIMD floating-point functions by running "
+ "with incorrect rounding modes."));
+ INSERT(Settings, cpuopt_unsafe_inaccurate_nan, tr("Inaccurate NaN handling"),
+ tr("This option improves speed by removing NaN checking. Please note this also reduces "
+ "accuracy of certain floating-point instructions."));
+ INSERT(Settings, cpuopt_unsafe_fastmem_check, tr("Disable address space checks"),
+ tr("This option improves speed by eliminating a safety check before every memory "
+ "read/write "
+ "in guest. Disabling it may allow a game to read/write the emulator's memory."));
+ INSERT(
+ Settings, cpuopt_unsafe_ignore_global_monitor, tr("Ignore global monitor"),
+ tr("This option improves speed by relying only on the semantics of cmpxchg to ensure "
"safety of exclusive access instructions. Please note this may result in deadlocks and "
- "other race conditions.");
+ "other race conditions."));
// Renderer
- INSERT(Settings, renderer_backend, "API:", "");
- INSERT(Settings, vulkan_device, "Device:", "");
- INSERT(Settings, shader_backend, "Shader Backend:", "");
- INSERT(Settings, resolution_setup, "Resolution:", "");
- INSERT(Settings, scaling_filter, "Window Adapting Filter:", "");
- INSERT(Settings, fsr_sharpening_slider, "FSR Sharpness:", "");
- INSERT(Settings, anti_aliasing, "Anti-Aliasing Method:", "");
- INSERT(Settings, fullscreen_mode, "Fullscreen Mode:", "");
- INSERT(Settings, aspect_ratio, "Aspect Ratio:", "");
- INSERT(Settings, use_disk_shader_cache, "Use disk pipeline cache", "");
- INSERT(Settings, use_asynchronous_gpu_emulation, "Use asynchronous GPU emulation", "");
- INSERT(Settings, nvdec_emulation, "NVDEC emulation:", "");
- INSERT(Settings, accelerate_astc, "ASTC Decoding Method:", "");
- INSERT(Settings, astc_recompression, "ASTC Recompression Method:", "");
- INSERT(Settings, vsync_mode, "VSync Mode:",
- "FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen "
+ INSERT(Settings, renderer_backend, tr("API:"), QStringLiteral());
+ INSERT(Settings, vulkan_device, tr("Device:"), QStringLiteral());
+ INSERT(Settings, shader_backend, tr("Shader Backend:"), QStringLiteral());
+ INSERT(Settings, resolution_setup, tr("Resolution:"), QStringLiteral());
+ INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral());
+ INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), QStringLiteral());
+ INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), QStringLiteral());
+ INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"), QStringLiteral());
+ INSERT(Settings, aspect_ratio, tr("Aspect Ratio:"), QStringLiteral());
+ INSERT(Settings, use_disk_shader_cache, tr("Use disk pipeline cache"), QStringLiteral());
+ INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"),
+ QStringLiteral());
+ INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), QStringLiteral());
+ INSERT(Settings, accelerate_astc, tr("ASTC Decoding Method:"), QStringLiteral());
+ INSERT(Settings, astc_recompression, tr("ASTC Recompression Method:"), QStringLiteral());
+ INSERT(
+ Settings, vsync_mode, tr("VSync Mode:"),
+ tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen "
"refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from "
"a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop "
"frames.\nImmediate (no synchronization) just presents whatever is available and can "
- "exhibit tearing.");
- INSERT(Settings, bg_red, "", "");
- INSERT(Settings, bg_green, "", "");
- INSERT(Settings, bg_blue, "", "");
+ "exhibit tearing."));
+ INSERT(Settings, bg_red, QStringLiteral(), QStringLiteral());
+ INSERT(Settings, bg_green, QStringLiteral(), QStringLiteral());
+ INSERT(Settings, bg_blue, QStringLiteral(), QStringLiteral());
// Renderer (Advanced Graphics)
- INSERT(Settings, async_presentation, "Enable asynchronous presentation (Vulkan only)", "");
- INSERT(Settings, renderer_force_max_clock, "Force maximum clocks (Vulkan only)",
- "Runs work in the background while waiting for graphics commands to keep the GPU from "
- "lowering its clock speed.");
- INSERT(Settings, max_anisotropy, "Anisotropic Filtering:", "");
- INSERT(Settings, gpu_accuracy, "Accuracy Level:", "");
- INSERT(Settings, use_asynchronous_shaders, "Use asynchronous shader building (Hack)",
- "Enables asynchronous shader compilation, which may reduce shader stutter. This feature "
- "is experimental.");
- INSERT(Settings, use_fast_gpu_time, "Use Fast GPU Time (Hack)",
- "Enables Fast GPU Time. This option will force most games to run at their highest "
- "native resolution.");
- INSERT(Settings, use_vulkan_driver_pipeline_cache, "Use Vulkan pipeline cache",
- "Enables GPU vendor-specific pipeline cache. This option can improve shader loading "
- "time significantly in cases where the Vulkan driver does not store pipeline cache "
- "files internally.");
- INSERT(Settings, enable_compute_pipelines, "Enable Compute Pipelines (Intel Vulkan Only)",
- "Enable compute pipelines, required by some games.\nThis setting only exists for Intel "
+ INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"),
+ QStringLiteral());
+ INSERT(
+ Settings, renderer_force_max_clock, tr("Force maximum clocks (Vulkan only)"),
+ tr("Runs work in the background while waiting for graphics commands to keep the GPU from "
+ "lowering its clock speed."));
+ INSERT(Settings, max_anisotropy, tr("Anisotropic Filtering:"), QStringLiteral());
+ INSERT(Settings, gpu_accuracy, tr("Accuracy Level:"), QStringLiteral());
+ INSERT(
+ Settings, use_asynchronous_shaders, tr("Use asynchronous shader building (Hack)"),
+ tr("Enables asynchronous shader compilation, which may reduce shader stutter. This feature "
+ "is experimental."));
+ INSERT(Settings, use_fast_gpu_time, tr("Use Fast GPU Time (Hack)"),
+ tr("Enables Fast GPU Time. This option will force most games to run at their highest "
+ "native resolution."));
+ INSERT(Settings, use_vulkan_driver_pipeline_cache, tr("Use Vulkan pipeline cache"),
+ tr("Enables GPU vendor-specific pipeline cache. This option can improve shader loading "
+ "time significantly in cases where the Vulkan driver does not store pipeline cache "
+ "files internally."));
+ INSERT(
+ Settings, enable_compute_pipelines, tr("Enable Compute Pipelines (Intel Vulkan Only)"),
+ tr("Enable compute pipelines, required by some games.\nThis setting only exists for Intel "
"proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled "
- "on all other drivers.");
- INSERT(Settings, use_reactive_flushing, "Enable Reactive Flushing",
- "Uses reactive flushing instead of predictive flushing, allowing more accurate memory "
- "syncing.");
- INSERT(Settings, use_video_framerate, "Sync to framerate of video playback",
- "Run the game at normal speed during video playback, even when the framerate is "
- "unlocked.");
- INSERT(Settings, barrier_feedback_loops, "Barrier feedback loops",
- "Improves rendering of transparency effects in specific games.");
+ "on all other drivers."));
+ INSERT(
+ Settings, use_reactive_flushing, tr("Enable Reactive Flushing"),
+ tr("Uses reactive flushing instead of predictive flushing, allowing more accurate memory "
+ "syncing."));
+ INSERT(Settings, use_video_framerate, tr("Sync to framerate of video playback"),
+ tr("Run the game at normal speed during video playback, even when the framerate is "
+ "unlocked."));
+ INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
+ tr("Improves rendering of transparency effects in specific games."));
// Renderer (Debug)
// System
- INSERT(Settings, rng_seed, "RNG Seed", "");
- INSERT(Settings, rng_seed_enabled, "", "");
- INSERT(Settings, device_name, "Device Name", "");
- INSERT(Settings, custom_rtc, "Custom RTC", "");
- INSERT(Settings, custom_rtc_enabled, "", "");
- INSERT(Settings, language_index,
- "Language:", "Note: this can be overridden when region setting is auto-select");
- INSERT(Settings, region_index, "Region:", "");
- INSERT(Settings, time_zone_index, "Time Zone:", "");
- INSERT(Settings, sound_index, "Sound Output Mode:", "");
- INSERT(Settings, use_docked_mode, "Console Mode:", "");
- INSERT(Settings, current_user, "", "");
+ INSERT(Settings, rng_seed, tr("RNG Seed"), QStringLiteral());
+ INSERT(Settings, rng_seed_enabled, QStringLiteral(), QStringLiteral());
+ INSERT(Settings, device_name, tr("Device Name"), QStringLiteral());
+ INSERT(Settings, custom_rtc, tr("Custom RTC"), QStringLiteral());
+ INSERT(Settings, custom_rtc_enabled, QStringLiteral(), QStringLiteral());
+ INSERT(Settings, language_index, tr("Language:"),
+ tr("Note: this can be overridden when region setting is auto-select"));
+ INSERT(Settings, region_index, tr("Region:"), QStringLiteral());
+ INSERT(Settings, time_zone_index, tr("Time Zone:"), QStringLiteral());
+ INSERT(Settings, sound_index, tr("Sound Output Mode:"), QStringLiteral());
+ INSERT(Settings, use_docked_mode, tr("Console Mode:"), QStringLiteral());
+ INSERT(Settings, current_user, QStringLiteral(), QStringLiteral());
// Controls
@@ -154,12 +167,14 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
// Ui
// Ui General
- INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", "");
- INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", "");
- INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", "");
- INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", "");
- INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", "");
- INSERT(UISettings, controller_applet_disabled, "Disable controller applet", "");
+ INSERT(UISettings, select_user_on_boot, tr("Prompt for user on game boot"), QStringLiteral());
+ INSERT(UISettings, pause_when_in_background, tr("Pause emulation when in background"),
+ QStringLiteral());
+ INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"),
+ QStringLiteral());
+ INSERT(UISettings, hide_mouse, tr("Hide mouse on inactivity"), QStringLiteral());
+ INSERT(UISettings, controller_applet_disabled, tr("Disable controller applet"),
+ QStringLiteral());
// Ui Debugging
@@ -179,140 +194,141 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
return parent->tr(text, context);
};
-#define PAIR(ENUM, VALUE, TRANSLATION) \
- { static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION) }
-#define CTX_PAIR(ENUM, VALUE, TRANSLATION, CONTEXT) \
- { static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION, CONTEXT) }
+#define PAIR(ENUM, VALUE, TRANSLATION) {static_cast<u32>(Settings::ENUM::VALUE), (TRANSLATION)}
// Intentionally skipping VSyncMode to let the UI fill that one out
translations->insert({Settings::EnumMetadata<Settings::AstcDecodeMode>::Index(),
{
- PAIR(AstcDecodeMode, Cpu, "CPU"),
- PAIR(AstcDecodeMode, Gpu, "GPU"),
- PAIR(AstcDecodeMode, CpuAsynchronous, "CPU Asynchronous"),
- }});
- translations->insert({Settings::EnumMetadata<Settings::AstcRecompression>::Index(),
- {
- PAIR(AstcRecompression, Uncompressed, "Uncompressed (Best quality)"),
- PAIR(AstcRecompression, Bc1, "BC1 (Low quality)"),
- PAIR(AstcRecompression, Bc3, "BC3 (Medium quality)"),
+ PAIR(AstcDecodeMode, Cpu, tr("CPU")),
+ PAIR(AstcDecodeMode, Gpu, tr("GPU")),
+ PAIR(AstcDecodeMode, CpuAsynchronous, tr("CPU Asynchronous")),
}});
+ translations->insert(
+ {Settings::EnumMetadata<Settings::AstcRecompression>::Index(),
+ {
+ PAIR(AstcRecompression, Uncompressed, tr("Uncompressed (Best quality)")),
+ PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")),
+ PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")),
+ }});
translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(),
{
#ifdef HAS_OPENGL
- PAIR(RendererBackend, OpenGL, "OpenGL"),
+ PAIR(RendererBackend, OpenGL, tr("OpenGL")),
#endif
- PAIR(RendererBackend, Vulkan, "Vulkan"),
- PAIR(RendererBackend, Null, "Null"),
- }});
- translations->insert({Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
- {
- PAIR(ShaderBackend, Glsl, "GLSL"),
- PAIR(ShaderBackend, Glasm, "GLASM (Assembly Shaders, NVIDIA Only)"),
- PAIR(ShaderBackend, SpirV, "SPIR-V (Experimental, Mesa Only)"),
+ PAIR(RendererBackend, Vulkan, tr("Vulkan")),
+ PAIR(RendererBackend, Null, tr("Null")),
}});
+ translations->insert(
+ {Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
+ {
+ PAIR(ShaderBackend, Glsl, tr("GLSL")),
+ PAIR(ShaderBackend, Glasm, tr("GLASM (Assembly Shaders, NVIDIA Only)")),
+ PAIR(ShaderBackend, SpirV, tr("SPIR-V (Experimental, Mesa Only)")),
+ }});
translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(),
{
- PAIR(GpuAccuracy, Normal, "Normal"),
- PAIR(GpuAccuracy, High, "High"),
- PAIR(GpuAccuracy, Extreme, "Extreme"),
- }});
- translations->insert({Settings::EnumMetadata<Settings::CpuAccuracy>::Index(),
- {
- PAIR(CpuAccuracy, Auto, "Auto"),
- PAIR(CpuAccuracy, Accurate, "Accurate"),
- PAIR(CpuAccuracy, Unsafe, "Unsafe"),
- PAIR(CpuAccuracy, Paranoid, "Paranoid (disables most optimizations)"),
+ PAIR(GpuAccuracy, Normal, tr("Normal")),
+ PAIR(GpuAccuracy, High, tr("High")),
+ PAIR(GpuAccuracy, Extreme, tr("Extreme")),
}});
+ translations->insert(
+ {Settings::EnumMetadata<Settings::CpuAccuracy>::Index(),
+ {
+ PAIR(CpuAccuracy, Auto, tr("Auto")),
+ PAIR(CpuAccuracy, Accurate, tr("Accurate")),
+ PAIR(CpuAccuracy, Unsafe, tr("Unsafe")),
+ PAIR(CpuAccuracy, Paranoid, tr("Paranoid (disables most optimizations)")),
+ }});
translations->insert({Settings::EnumMetadata<Settings::FullscreenMode>::Index(),
{
- PAIR(FullscreenMode, Borderless, "Borderless Windowed"),
- PAIR(FullscreenMode, Exclusive, "Exclusive Fullscreen"),
+ PAIR(FullscreenMode, Borderless, tr("Borderless Windowed")),
+ PAIR(FullscreenMode, Exclusive, tr("Exclusive Fullscreen")),
}});
translations->insert({Settings::EnumMetadata<Settings::NvdecEmulation>::Index(),
{
- PAIR(NvdecEmulation, Off, "No Video Output"),
- PAIR(NvdecEmulation, Cpu, "CPU Video Decoding"),
- PAIR(NvdecEmulation, Gpu, "GPU Video Decoding (Default)"),
- }});
- translations->insert({Settings::EnumMetadata<Settings::ResolutionSetup>::Index(),
- {
- PAIR(ResolutionSetup, Res1_2X, "0.5X (360p/540p) [EXPERIMENTAL]"),
- PAIR(ResolutionSetup, Res3_4X, "0.75X (540p/810p) [EXPERIMENTAL]"),
- PAIR(ResolutionSetup, Res1X, "1X (720p/1080p)"),
- PAIR(ResolutionSetup, Res3_2X, "1.5X (1080p/1620p) [EXPERIMENTAL]"),
- PAIR(ResolutionSetup, Res2X, "2X (1440p/2160p)"),
- PAIR(ResolutionSetup, Res3X, "3X (2160p/3240p)"),
- PAIR(ResolutionSetup, Res4X, "4X (2880p/4320p)"),
- PAIR(ResolutionSetup, Res5X, "5X (3600p/5400p)"),
- PAIR(ResolutionSetup, Res6X, "6X (4320p/6480p)"),
- PAIR(ResolutionSetup, Res7X, "7X (5040p/7560p)"),
- PAIR(ResolutionSetup, Res8X, "8X (5760p/8640p)"),
+ PAIR(NvdecEmulation, Off, tr("No Video Output")),
+ PAIR(NvdecEmulation, Cpu, tr("CPU Video Decoding")),
+ PAIR(NvdecEmulation, Gpu, tr("GPU Video Decoding (Default)")),
}});
+ translations->insert(
+ {Settings::EnumMetadata<Settings::ResolutionSetup>::Index(),
+ {
+ PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")),
+ PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")),
+ PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")),
+ PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")),
+ PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")),
+ PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")),
+ PAIR(ResolutionSetup, Res4X, tr("4X (2880p/4320p)")),
+ PAIR(ResolutionSetup, Res5X, tr("5X (3600p/5400p)")),
+ PAIR(ResolutionSetup, Res6X, tr("6X (4320p/6480p)")),
+ PAIR(ResolutionSetup, Res7X, tr("7X (5040p/7560p)")),
+ PAIR(ResolutionSetup, Res8X, tr("8X (5760p/8640p)")),
+ }});
translations->insert({Settings::EnumMetadata<Settings::ScalingFilter>::Index(),
{
- PAIR(ScalingFilter, NearestNeighbor, "Nearest Neighbor"),
- PAIR(ScalingFilter, Bilinear, "Bilinear"),
- PAIR(ScalingFilter, Bicubic, "Bicubic"),
- PAIR(ScalingFilter, Gaussian, "Gaussian"),
- PAIR(ScalingFilter, ScaleForce, "ScaleForce"),
- PAIR(ScalingFilter, Fsr, "AMD FidelityFX™️ Super Resolution"),
+ PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")),
+ PAIR(ScalingFilter, Bilinear, tr("Bilinear")),
+ PAIR(ScalingFilter, Bicubic, tr("Bicubic")),
+ PAIR(ScalingFilter, Gaussian, tr("Gaussian")),
+ PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")),
+ PAIR(ScalingFilter, Fsr, tr("AMD FidelityFX™️ Super Resolution")),
}});
translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
{
- PAIR(AntiAliasing, None, "None"),
- PAIR(AntiAliasing, Fxaa, "FXAA"),
- PAIR(AntiAliasing, Smaa, "SMAA"),
+ PAIR(AntiAliasing, None, tr("None")),
+ PAIR(AntiAliasing, Fxaa, tr("FXAA")),
+ PAIR(AntiAliasing, Smaa, tr("SMAA")),
}});
translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(),
{
- PAIR(AspectRatio, R16_9, "Default (16:9)"),
- PAIR(AspectRatio, R4_3, "Force 4:3"),
- PAIR(AspectRatio, R21_9, "Force 21:9"),
- PAIR(AspectRatio, R16_10, "Force 16:10"),
- PAIR(AspectRatio, Stretch, "Stretch to Window"),
+ PAIR(AspectRatio, R16_9, tr("Default (16:9)")),
+ PAIR(AspectRatio, R4_3, tr("Force 4:3")),
+ PAIR(AspectRatio, R21_9, tr("Force 21:9")),
+ PAIR(AspectRatio, R16_10, tr("Force 16:10")),
+ PAIR(AspectRatio, Stretch, tr("Stretch to Window")),
}});
translations->insert({Settings::EnumMetadata<Settings::AnisotropyMode>::Index(),
{
- PAIR(AnisotropyMode, Automatic, "Automatic"),
- PAIR(AnisotropyMode, Default, "Default"),
- PAIR(AnisotropyMode, X2, "2x"),
- PAIR(AnisotropyMode, X4, "4x"),
- PAIR(AnisotropyMode, X8, "8x"),
- PAIR(AnisotropyMode, X16, "16x"),
+ PAIR(AnisotropyMode, Automatic, tr("Automatic")),
+ PAIR(AnisotropyMode, Default, tr("Default")),
+ PAIR(AnisotropyMode, X2, tr("2x")),
+ PAIR(AnisotropyMode, X4, tr("4x")),
+ PAIR(AnisotropyMode, X8, tr("8x")),
+ PAIR(AnisotropyMode, X16, tr("16x")),
}});
translations->insert(
{Settings::EnumMetadata<Settings::Language>::Index(),
{
- PAIR(Language, Japanese, "Japanese (日本語)"),
- PAIR(Language, EnglishAmerican, "American English"),
- PAIR(Language, French, "French (français)"),
- PAIR(Language, German, "German (Deutsch)"),
- PAIR(Language, Italian, "Italian (italiano)"),
- PAIR(Language, Spanish, "Spanish (español)"),
- PAIR(Language, Chinese, "Chinese"),
- PAIR(Language, Korean, "Korean (한국어)"),
- PAIR(Language, Dutch, "Dutch (Nederlands)"),
- PAIR(Language, Portuguese, "Portuguese (português)"),
- PAIR(Language, Russian, "Russian (Русский)"),
- PAIR(Language, Taiwanese, "Taiwanese"),
- PAIR(Language, EnglishBritish, "British English"),
- PAIR(Language, FrenchCanadian, "Canadian French"),
- PAIR(Language, SpanishLatin, "Latin American Spanish"),
- PAIR(Language, ChineseSimplified, "Simplified Chinese"),
- PAIR(Language, ChineseTraditional, "Traditional Chinese (正體中文)"),
- PAIR(Language, PortugueseBrazilian, "Brazilian Portuguese (português do Brasil)"),
+ PAIR(Language, Japanese, tr("Japanese (日本語)")),
+ PAIR(Language, EnglishAmerican, tr("American English")),
+ PAIR(Language, French, tr("French (français)")),
+ PAIR(Language, German, tr("German (Deutsch)")),
+ PAIR(Language, Italian, tr("Italian (italiano)")),
+ PAIR(Language, Spanish, tr("Spanish (español)")),
+ PAIR(Language, Chinese, tr("Chinese")),
+ PAIR(Language, Korean, tr("Korean (한국어)")),
+ PAIR(Language, Dutch, tr("Dutch (Nederlands)")),
+ PAIR(Language, Portuguese, tr("Portuguese (português)")),
+ PAIR(Language, Russian, tr("Russian (Русский)")),
+ PAIR(Language, Taiwanese, tr("Taiwanese")),
+ PAIR(Language, EnglishBritish, tr("British English")),
+ PAIR(Language, FrenchCanadian, tr("Canadian French")),
+ PAIR(Language, SpanishLatin, tr("Latin American Spanish")),
+ PAIR(Language, ChineseSimplified, tr("Simplified Chinese")),
+ PAIR(Language, ChineseTraditional, tr("Traditional Chinese (正體中文)")),
+ PAIR(Language, PortugueseBrazilian, tr("Brazilian Portuguese (português do Brasil)")),
}});
translations->insert({Settings::EnumMetadata<Settings::Region>::Index(),
{
- PAIR(Region, Japan, "Japan"),
- PAIR(Region, Usa, "USA"),
- PAIR(Region, Europe, "Europe"),
- PAIR(Region, Australia, "Australia"),
- PAIR(Region, China, "China"),
- PAIR(Region, Korea, "Korea"),
- PAIR(Region, Taiwan, "Taiwan"),
+ PAIR(Region, Japan, tr("Japan")),
+ PAIR(Region, Usa, tr("USA")),
+ PAIR(Region, Europe, tr("Europe")),
+ PAIR(Region, Australia, tr("Australia")),
+ PAIR(Region, China, tr("China")),
+ PAIR(Region, Korea, tr("Korea")),
+ PAIR(Region, Taiwan, tr("Taiwan")),
}});
translations->insert(
{Settings::EnumMetadata<Settings::TimeZone>::Index(),
@@ -324,72 +340,74 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
{static_cast<u32>(Settings::TimeZone::Default),
tr("Default (%1)", "Default time zone")
.arg(QString::fromStdString(Common::TimeZone::GetDefaultTimeZone()))},
- PAIR(TimeZone, Cet, "CET"),
- PAIR(TimeZone, Cst6Cdt, "CST6CDT"),
- PAIR(TimeZone, Cuba, "Cuba"),
- PAIR(TimeZone, Eet, "EET"),
- PAIR(TimeZone, Egypt, "Egypt"),
- PAIR(TimeZone, Eire, "Eire"),
- PAIR(TimeZone, Est, "EST"),
- PAIR(TimeZone, Est5Edt, "EST5EDT"),
- PAIR(TimeZone, Gb, "GB"),
- PAIR(TimeZone, GbEire, "GB-Eire"),
- PAIR(TimeZone, Gmt, "GMT"),
- PAIR(TimeZone, GmtPlusZero, "GMT+0"),
- PAIR(TimeZone, GmtMinusZero, "GMT-0"),
- PAIR(TimeZone, GmtZero, "GMT0"),
- PAIR(TimeZone, Greenwich, "Greenwich"),
- PAIR(TimeZone, Hongkong, "Hongkong"),
- PAIR(TimeZone, Hst, "HST"),
- PAIR(TimeZone, Iceland, "Iceland"),
- PAIR(TimeZone, Iran, "Iran"),
- PAIR(TimeZone, Israel, "Israel"),
- PAIR(TimeZone, Jamaica, "Jamaica"),
- PAIR(TimeZone, Japan, "Japan"),
- PAIR(TimeZone, Kwajalein, "Kwajalein"),
- PAIR(TimeZone, Libya, "Libya"),
- PAIR(TimeZone, Met, "MET"),
- PAIR(TimeZone, Mst, "MST"),
- PAIR(TimeZone, Mst7Mdt, "MST7MDT"),
- PAIR(TimeZone, Navajo, "Navajo"),
- PAIR(TimeZone, Nz, "NZ"),
- PAIR(TimeZone, NzChat, "NZ-CHAT"),
- PAIR(TimeZone, Poland, "Poland"),
- PAIR(TimeZone, Portugal, "Portugal"),
- PAIR(TimeZone, Prc, "PRC"),
- PAIR(TimeZone, Pst8Pdt, "PST8PDT"),
- PAIR(TimeZone, Roc, "ROC"),
- PAIR(TimeZone, Rok, "ROK"),
- PAIR(TimeZone, Singapore, "Singapore"),
- PAIR(TimeZone, Turkey, "Turkey"),
- PAIR(TimeZone, Uct, "UCT"),
- PAIR(TimeZone, Universal, "Universal"),
- PAIR(TimeZone, Utc, "UTC"),
- PAIR(TimeZone, WSu, "W-SU"),
- PAIR(TimeZone, Wet, "WET"),
- PAIR(TimeZone, Zulu, "Zulu"),
+ PAIR(TimeZone, Cet, tr("CET")),
+ PAIR(TimeZone, Cst6Cdt, tr("CST6CDT")),
+ PAIR(TimeZone, Cuba, tr("Cuba")),
+ PAIR(TimeZone, Eet, tr("EET")),
+ PAIR(TimeZone, Egypt, tr("Egypt")),
+ PAIR(TimeZone, Eire, tr("Eire")),
+ PAIR(TimeZone, Est, tr("EST")),
+ PAIR(TimeZone, Est5Edt, tr("EST5EDT")),
+ PAIR(TimeZone, Gb, tr("GB")),
+ PAIR(TimeZone, GbEire, tr("GB-Eire")),
+ PAIR(TimeZone, Gmt, tr("GMT")),
+ PAIR(TimeZone, GmtPlusZero, tr("GMT+0")),
+ PAIR(TimeZone, GmtMinusZero, tr("GMT-0")),
+ PAIR(TimeZone, GmtZero, tr("GMT0")),
+ PAIR(TimeZone, Greenwich, tr("Greenwich")),
+ PAIR(TimeZone, Hongkong, tr("Hongkong")),
+ PAIR(TimeZone, Hst, tr("HST")),
+ PAIR(TimeZone, Iceland, tr("Iceland")),
+ PAIR(TimeZone, Iran, tr("Iran")),
+ PAIR(TimeZone, Israel, tr("Israel")),
+ PAIR(TimeZone, Jamaica, tr("Jamaica")),
+ PAIR(TimeZone, Japan, tr("Japan")),
+ PAIR(TimeZone, Kwajalein, tr("Kwajalein")),
+ PAIR(TimeZone, Libya, tr("Libya")),
+ PAIR(TimeZone, Met, tr("MET")),
+ PAIR(TimeZone, Mst, tr("MST")),
+ PAIR(TimeZone, Mst7Mdt, tr("MST7MDT")),
+ PAIR(TimeZone, Navajo, tr("Navajo")),
+ PAIR(TimeZone, Nz, tr("NZ")),
+ PAIR(TimeZone, NzChat, tr("NZ-CHAT")),
+ PAIR(TimeZone, Poland, tr("Poland")),
+ PAIR(TimeZone, Portugal, tr("Portugal")),
+ PAIR(TimeZone, Prc, tr("PRC")),
+ PAIR(TimeZone, Pst8Pdt, tr("PST8PDT")),
+ PAIR(TimeZone, Roc, tr("ROC")),
+ PAIR(TimeZone, Rok, tr("ROK")),
+ PAIR(TimeZone, Singapore, tr("Singapore")),
+ PAIR(TimeZone, Turkey, tr("Turkey")),
+ PAIR(TimeZone, Uct, tr("UCT")),
+ PAIR(TimeZone, Universal, tr("Universal")),
+ PAIR(TimeZone, Utc, tr("UTC")),
+ PAIR(TimeZone, WSu, tr("W-SU")),
+ PAIR(TimeZone, Wet, tr("WET")),
+ PAIR(TimeZone, Zulu, tr("Zulu")),
}});
translations->insert({Settings::EnumMetadata<Settings::AudioMode>::Index(),
{
- PAIR(AudioMode, Mono, "Mono"),
- PAIR(AudioMode, Stereo, "Stereo"),
- PAIR(AudioMode, Surround, "Surround"),
+ PAIR(AudioMode, Mono, tr("Mono")),
+ PAIR(AudioMode, Stereo, tr("Stereo")),
+ PAIR(AudioMode, Surround, tr("Surround")),
}});
translations->insert({Settings::EnumMetadata<Settings::MemoryLayout>::Index(),
{
- PAIR(MemoryLayout, Memory_4Gb, "4GB DRAM (Default)"),
- PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"),
- PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"),
+ PAIR(MemoryLayout, Memory_4Gb, tr("4GB DRAM (Default)")),
+ PAIR(MemoryLayout, Memory_6Gb, tr("6GB DRAM (Unsafe)")),
+ PAIR(MemoryLayout, Memory_8Gb, tr("8GB DRAM (Unsafe)")),
+ }});
+ translations->insert({Settings::EnumMetadata<Settings::ConsoleMode>::Index(),
+ {
+ PAIR(ConsoleMode, Docked, tr("Docked")),
+ PAIR(ConsoleMode, Handheld, tr("Handheld")),
}});
- translations->insert(
- {Settings::EnumMetadata<Settings::ConsoleMode>::Index(),
- {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}});
translations->insert(
{Settings::EnumMetadata<Settings::ConfirmStop>::Index(),
{
- PAIR(ConfirmStop, Ask_Always, "Always ask (Default)"),
- PAIR(ConfirmStop, Ask_Based_On_Game, "Only if game specifies not to stop"),
- PAIR(ConfirmStop, Ask_Never, "Never ask"),
+ PAIR(ConfirmStop, Ask_Always, tr("Always ask (Default)")),
+ PAIR(ConfirmStop, Ask_Based_On_Game, tr("Only if game specifies not to stop")),
+ PAIR(ConfirmStop, Ask_Never, tr("Never ask")),
}});
#undef PAIR
diff --git a/src/yuzu/configuration/shared_translation.h b/src/yuzu/configuration/shared_translation.h
index 99a0e808c..d5fc3b8de 100644
--- a/src/yuzu/configuration/shared_translation.h
+++ b/src/yuzu/configuration/shared_translation.h
@@ -10,6 +10,7 @@
#include <vector>
#include <QString>
#include "common/common_types.h"
+#include "common/settings.h"
class QWidget;
@@ -22,4 +23,46 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent);
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent);
+static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map = {
+ {Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "None"))},
+ {Settings::AntiAliasing::Fxaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FXAA"))},
+ {Settings::AntiAliasing::Smaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SMAA"))},
+};
+
+static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map = {
+ {Settings::ScalingFilter::NearestNeighbor,
+ QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Nearest"))},
+ {Settings::ScalingFilter::Bilinear,
+ QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
+ {Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
+ {Settings::ScalingFilter::Gaussian,
+ QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
+ {Settings::ScalingFilter::ScaleForce,
+ QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
+ {Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
+};
+
+static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
+ {Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))},
+ {Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))},
+};
+
+static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map = {
+ {Settings::GpuAccuracy::Normal, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Normal"))},
+ {Settings::GpuAccuracy::High, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "High"))},
+ {Settings::GpuAccuracy::Extreme, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Extreme"))},
+};
+
+static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map = {
+ {Settings::RendererBackend::Vulkan, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Vulkan"))},
+ {Settings::RendererBackend::OpenGL, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "OpenGL"))},
+ {Settings::RendererBackend::Null, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Null"))},
+};
+
+static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map = {
+ {Settings::ShaderBackend::Glsl, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLSL"))},
+ {Settings::ShaderBackend::Glasm, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLASM"))},
+ {Settings::ShaderBackend::SpirV, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SPIRV"))},
+};
+
} // namespace ConfigurationShared
diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp
index ea8d7add4..941683a43 100644
--- a/src/yuzu/configuration/shared_widget.cpp
+++ b/src/yuzu/configuration/shared_widget.cpp
@@ -194,7 +194,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
return group;
}
- const auto get_selected = [=]() -> int {
+ const auto get_selected = [this]() -> int {
for (const auto& [id, button] : radio_buttons) {
if (button->isChecked()) {
return id;
@@ -203,7 +203,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
return -1;
};
- const auto set_index = [=](u32 value) {
+ const auto set_index = [this](u32 value) {
for (const auto& [id, button] : radio_buttons) {
button->setChecked(id == value);
}
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 7049c57b6..6d227ef8d 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -36,10 +36,8 @@ constexpr std::array<std::array<Qt::GlobalColor, 2>, 10> WaitTreeColors{{
bool IsDarkTheme() {
const auto& theme = UISettings::values.theme;
- return theme == QStringLiteral("qdarkstyle") ||
- theme == QStringLiteral("qdarkstyle_midnight_blue") ||
- theme == QStringLiteral("colorful_dark") ||
- theme == QStringLiteral("colorful_midnight_blue");
+ return theme == std::string("qdarkstyle") || theme == std::string("qdarkstyle_midnight_blue") ||
+ theme == std::string("colorful_dark") || theme == std::string("colorful_midnight_blue");
}
} // namespace
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 7e7d8e252..59b317135 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -278,7 +278,7 @@ void GameList::OnUpdateThemedIcons() {
case GameListItemType::CustomDir: {
const UISettings::GameDir& game_dir =
UISettings::values.game_dirs[child->data(GameListDir::GameDirRole).toInt()];
- const QString icon_name = QFileInfo::exists(game_dir.path)
+ const QString icon_name = QFileInfo::exists(QString::fromStdString(game_dir.path))
? QStringLiteral("folder")
: QStringLiteral("bad_folder");
child->setData(
@@ -567,9 +567,10 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
QAction* verify_integrity = context_menu.addAction(tr("Verify Integrity"));
QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard"));
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
+// TODO: Implement shortcut creation for macOS
+#if !defined(__APPLE__)
QMenu* shortcut_menu = context_menu.addMenu(tr("Create Shortcut"));
QAction* create_desktop_shortcut = shortcut_menu->addAction(tr("Add to Desktop"));
-#ifndef WIN32
QAction* create_applications_menu_shortcut =
shortcut_menu->addAction(tr("Add to Applications Menu"));
#endif
@@ -647,10 +648,11 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
connect(navigate_to_gamedb_entry, &QAction::triggered, [this, program_id]() {
emit NavigateToGamedbEntryRequested(program_id, compatibility_list);
});
+// TODO: Implement shortcut creation for macOS
+#if !defined(__APPLE__)
connect(create_desktop_shortcut, &QAction::triggered, [this, program_id, path]() {
emit CreateShortcut(program_id, path, GameListShortcutTarget::Desktop);
});
-#ifndef WIN32
connect(create_applications_menu_shortcut, &QAction::triggered, [this, program_id, path]() {
emit CreateShortcut(program_id, path, GameListShortcutTarget::Applications);
});
@@ -725,7 +727,8 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
});
connect(open_directory_location, &QAction::triggered, [this, game_dir_index] {
- emit OpenDirectory(UISettings::values.game_dirs[game_dir_index].path);
+ emit OpenDirectory(
+ QString::fromStdString(UISettings::values.game_dirs[game_dir_index].path));
});
}
@@ -867,7 +870,7 @@ const QStringList GameList::supported_file_extensions = {
QStringLiteral("xci"), QStringLiteral("nsp"), QStringLiteral("kip")};
void GameList::RefreshGameDirectory() {
- if (!UISettings::values.game_dirs.isEmpty() && current_worker != nullptr) {
+ if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
PopulateAsync(UISettings::values.game_dirs);
}
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 86a0c41d9..c330b574f 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -286,13 +286,13 @@ public:
setData(QObject::tr("System Titles"), Qt::DisplayRole);
break;
case GameListItemType::CustomDir: {
- const QString icon_name = QFileInfo::exists(game_dir->path)
- ? QStringLiteral("folder")
- : QStringLiteral("bad_folder");
+ const QString path = QString::fromStdString(game_dir->path);
+ const QString icon_name =
+ QFileInfo::exists(path) ? QStringLiteral("folder") : QStringLiteral("bad_folder");
setData(QIcon::fromTheme(icon_name).pixmap(icon_size).scaled(
icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
Qt::DecorationRole);
- setData(game_dir->path, Qt::DisplayRole);
+ setData(path, Qt::DisplayRole);
break;
}
default:
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index 69be21027..dc006832e 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -456,29 +456,29 @@ void GameListWorker::run() {
break;
}
- if (game_dir.path == QStringLiteral("SDMC")) {
+ if (game_dir.path == std::string("SDMC")) {
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SdmcDir);
DirEntryReady(game_list_dir);
AddTitlesToGameList(game_list_dir);
- } else if (game_dir.path == QStringLiteral("UserNAND")) {
+ } else if (game_dir.path == std::string("UserNAND")) {
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::UserNandDir);
DirEntryReady(game_list_dir);
AddTitlesToGameList(game_list_dir);
- } else if (game_dir.path == QStringLiteral("SysNAND")) {
+ } else if (game_dir.path == std::string("SysNAND")) {
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SysNandDir);
DirEntryReady(game_list_dir);
AddTitlesToGameList(game_list_dir);
} else {
- watch_list.append(game_dir.path);
+ watch_list.append(QString::fromStdString(game_dir.path));
auto* const game_list_dir = new GameListDir(game_dir);
DirEntryReady(game_list_dir);
- ScanFileSystem(ScanTarget::FillManualContentProvider, game_dir.path.toStdString(),
- game_dir.deep_scan, game_list_dir);
- ScanFileSystem(ScanTarget::PopulateGameList, game_dir.path.toStdString(),
- game_dir.deep_scan, game_list_dir);
+ ScanFileSystem(ScanTarget::FillManualContentProvider, game_dir.path, game_dir.deep_scan,
+ game_list_dir);
+ ScanFileSystem(ScanTarget::PopulateGameList, game_dir.path, game_dir.deep_scan,
+ game_list_dir);
}
}
- RecordEvent([=](GameList* game_list) { game_list->DonePopulating(watch_list); });
+ RecordEvent([this](GameList* game_list) { game_list->DonePopulating(watch_list); });
processing_completed.Set();
}
diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp
index 6530186c1..eebfbf155 100644
--- a/src/yuzu/hotkeys.cpp
+++ b/src/yuzu/hotkeys.cpp
@@ -19,7 +19,7 @@ void HotkeyRegistry::SaveHotkeys() {
for (const auto& hotkey : group.second) {
UISettings::values.shortcuts.push_back(
{hotkey.first, group.first,
- UISettings::ContextualShortcut({hotkey.second.keyseq.toString(),
+ UISettings::ContextualShortcut({hotkey.second.keyseq.toString().toStdString(),
hotkey.second.controller_keyseq,
hotkey.second.context, hotkey.second.repeat})});
}
@@ -31,12 +31,12 @@ void HotkeyRegistry::LoadHotkeys() {
// beginGroup()
for (auto shortcut : UISettings::values.shortcuts) {
Hotkey& hk = hotkey_groups[shortcut.group][shortcut.name];
- if (!shortcut.shortcut.keyseq.isEmpty()) {
- hk.keyseq =
- QKeySequence::fromString(shortcut.shortcut.keyseq, QKeySequence::NativeText);
+ if (!shortcut.shortcut.keyseq.empty()) {
+ hk.keyseq = QKeySequence::fromString(QString::fromStdString(shortcut.shortcut.keyseq),
+ QKeySequence::NativeText);
hk.context = static_cast<Qt::ShortcutContext>(shortcut.shortcut.context);
}
- if (!shortcut.shortcut.controller_keyseq.isEmpty()) {
+ if (!shortcut.shortcut.controller_keyseq.empty()) {
hk.controller_keyseq = shortcut.shortcut.controller_keyseq;
}
if (hk.shortcut) {
@@ -51,7 +51,8 @@ void HotkeyRegistry::LoadHotkeys() {
}
}
-QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) {
+QShortcut* HotkeyRegistry::GetHotkey(const std::string& group, const std::string& action,
+ QWidget* widget) {
Hotkey& hk = hotkey_groups[group][action];
if (!hk.shortcut) {
@@ -62,7 +63,8 @@ QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action
return hk.shortcut;
}
-ControllerShortcut* HotkeyRegistry::GetControllerHotkey(const QString& group, const QString& action,
+ControllerShortcut* HotkeyRegistry::GetControllerHotkey(const std::string& group,
+ const std::string& action,
Core::HID::EmulatedController* controller) {
Hotkey& hk = hotkey_groups[group][action];
@@ -74,12 +76,12 @@ ControllerShortcut* HotkeyRegistry::GetControllerHotkey(const QString& group, co
return hk.controller_shortcut;
}
-QKeySequence HotkeyRegistry::GetKeySequence(const QString& group, const QString& action) {
+QKeySequence HotkeyRegistry::GetKeySequence(const std::string& group, const std::string& action) {
return hotkey_groups[group][action].keyseq;
}
-Qt::ShortcutContext HotkeyRegistry::GetShortcutContext(const QString& group,
- const QString& action) {
+Qt::ShortcutContext HotkeyRegistry::GetShortcutContext(const std::string& group,
+ const std::string& action) {
return hotkey_groups[group][action].context;
}
@@ -101,10 +103,10 @@ void ControllerShortcut::SetKey(const ControllerButtonSequence& buttons) {
button_sequence = buttons;
}
-void ControllerShortcut::SetKey(const QString& buttons_shortcut) {
+void ControllerShortcut::SetKey(const std::string& buttons_shortcut) {
ControllerButtonSequence sequence{};
- name = buttons_shortcut.toStdString();
- std::istringstream command_line(buttons_shortcut.toStdString());
+ name = buttons_shortcut;
+ std::istringstream command_line(buttons_shortcut);
std::string line;
while (std::getline(command_line, line, '+')) {
if (line.empty()) {
diff --git a/src/yuzu/hotkeys.h b/src/yuzu/hotkeys.h
index 56eee8d82..e11332d2e 100644
--- a/src/yuzu/hotkeys.h
+++ b/src/yuzu/hotkeys.h
@@ -33,7 +33,7 @@ public:
~ControllerShortcut();
void SetKey(const ControllerButtonSequence& buttons);
- void SetKey(const QString& buttons_shortcut);
+ void SetKey(const std::string& buttons_shortcut);
ControllerButtonSequence ButtonSequence() const;
@@ -88,8 +88,8 @@ public:
* will be the same. Thus, you shouldn't rely on the caller really being the
* QShortcut's parent.
*/
- QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget);
- ControllerShortcut* GetControllerHotkey(const QString& group, const QString& action,
+ QShortcut* GetHotkey(const std::string& group, const std::string& action, QWidget* widget);
+ ControllerShortcut* GetControllerHotkey(const std::string& group, const std::string& action,
Core::HID::EmulatedController* controller);
/**
@@ -98,7 +98,7 @@ public:
* @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger").
* @param action Name of the action (e.g. "Start Emulation", "Load Image").
*/
- QKeySequence GetKeySequence(const QString& group, const QString& action);
+ QKeySequence GetKeySequence(const std::string& group, const std::string& action);
/**
* Returns a Qt::ShortcutContext object who can be connected to other
@@ -108,20 +108,20 @@ public:
* "Debugger").
* @param action Name of the action (e.g. "Start Emulation", "Load Image").
*/
- Qt::ShortcutContext GetShortcutContext(const QString& group, const QString& action);
+ Qt::ShortcutContext GetShortcutContext(const std::string& group, const std::string& action);
private:
struct Hotkey {
QKeySequence keyseq;
- QString controller_keyseq;
+ std::string controller_keyseq;
QShortcut* shortcut = nullptr;
ControllerShortcut* controller_shortcut = nullptr;
Qt::ShortcutContext context = Qt::WindowShortcut;
bool repeat;
};
- using HotkeyMap = std::map<QString, Hotkey>;
- using HotkeyGroupMap = std::map<QString, HotkeyMap>;
+ using HotkeyMap = std::map<std::string, Hotkey>;
+ using HotkeyGroupMap = std::map<std::string, HotkeyMap>;
HotkeyGroupMap hotkey_groups;
};
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 0df163029..dcf68460a 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -10,6 +10,7 @@
#include <thread>
#include "core/loader/nca.h"
#include "core/tools/renderdoc.h"
+
#ifdef __APPLE__
#include <unistd.h> // for chdir
#endif
@@ -46,6 +47,7 @@
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/am/applets/applets.h"
+#include "core/hle/service/set/set_sys.h"
#include "yuzu/multiplayer/state.h"
#include "yuzu/util/controller_navigation.h"
@@ -127,6 +129,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "core/loader/loader.h"
#include "core/perf_stats.h"
#include "core/telemetry_session.h"
+#include "frontend_common/config.h"
#include "input_common/drivers/tas_input.h"
#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/main.h"
@@ -139,9 +142,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "yuzu/bootmanager.h"
#include "yuzu/compatdb.h"
#include "yuzu/compatibility_list.h"
-#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_dialog.h"
#include "yuzu/configuration/configure_input_per_game.h"
+#include "yuzu/configuration/qt_config.h"
#include "yuzu/debugger/console.h"
#include "yuzu/debugger/controller.h"
#include "yuzu/debugger/profiler.h"
@@ -310,7 +313,7 @@ bool GMainWindow::CheckDarkMode() {
#endif // __unix__
}
-GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan)
+GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulkan)
: ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()},
input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, config{std::move(config_)},
vfs{std::make_shared<FileSys::RealVfsFilesystem>()},
@@ -675,7 +678,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
// Don't forget to apply settings.
system->HIDCore().DisableAllControllerConfiguration();
system->ApplySettings();
- config->Save();
+ config->SaveAllValues();
UpdateStatusButtons();
@@ -1046,7 +1049,12 @@ void GMainWindow::InitializeWidgets() {
statusBar()->addPermanentWidget(label);
}
- // TODO (flTobi): Add the widget when multiplayer is fully implemented
+ firmware_label = new QLabel();
+ firmware_label->setObjectName(QStringLiteral("FirmwareLabel"));
+ firmware_label->setVisible(false);
+ firmware_label->setFocusPolicy(Qt::NoFocus);
+ statusBar()->addPermanentWidget(firmware_label);
+
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0);
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
@@ -1064,12 +1072,6 @@ void GMainWindow::InitializeWidgets() {
volume_slider->setObjectName(QStringLiteral("volume_slider"));
volume_slider->setMaximum(200);
volume_slider->setPageStep(5);
- connect(volume_slider, &QSlider::valueChanged, this, [this](int percentage) {
- Settings::values.audio_muted = false;
- const auto volume = static_cast<u8>(percentage);
- Settings::values.volume.SetValue(volume);
- UpdateVolumeUI();
- });
volume_popup->layout()->addWidget(volume_slider);
volume_button = new VolumeButton();
@@ -1077,6 +1079,12 @@ void GMainWindow::InitializeWidgets() {
volume_button->setFocusPolicy(Qt::NoFocus);
volume_button->setCheckable(true);
UpdateVolumeUI();
+ connect(volume_slider, &QSlider::valueChanged, this, [this](int percentage) {
+ Settings::values.audio_muted = false;
+ const auto volume = static_cast<u8>(percentage);
+ Settings::values.volume.SetValue(volume);
+ UpdateVolumeUI();
+ });
connect(volume_button, &QPushButton::clicked, this, [&] {
UpdateVolumeUI();
volume_popup->setVisible(!volume_popup->isVisible());
@@ -1128,7 +1136,7 @@ void GMainWindow::InitializeWidgets() {
connect(aa_status_button, &QPushButton::customContextMenuRequested,
[this](const QPoint& menu_location) {
QMenu context_menu;
- for (auto const& aa_text_pair : Config::anti_aliasing_texts_map) {
+ for (auto const& aa_text_pair : ConfigurationShared::anti_aliasing_texts_map) {
context_menu.addAction(aa_text_pair.second, [this, aa_text_pair] {
Settings::values.anti_aliasing.SetValue(aa_text_pair.first);
UpdateAAText();
@@ -1152,7 +1160,7 @@ void GMainWindow::InitializeWidgets() {
connect(filter_status_button, &QPushButton::customContextMenuRequested,
[this](const QPoint& menu_location) {
QMenu context_menu;
- for (auto const& filter_text_pair : Config::scaling_filter_texts_map) {
+ for (auto const& filter_text_pair : ConfigurationShared::scaling_filter_texts_map) {
context_menu.addAction(filter_text_pair.second, [this, filter_text_pair] {
Settings::values.scaling_filter.SetValue(filter_text_pair.first);
UpdateFilterText();
@@ -1175,7 +1183,7 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) {
QMenu context_menu;
- for (auto const& pair : Config::use_docked_mode_texts_map) {
+ for (auto const& pair : ConfigurationShared::use_docked_mode_texts_map) {
context_menu.addAction(pair.second, [this, &pair] {
if (pair.first != Settings::values.use_docked_mode.GetValue()) {
OnToggleDockedMode();
@@ -1199,7 +1207,7 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) {
QMenu context_menu;
- for (auto const& gpu_accuracy_pair : Config::gpu_accuracy_texts_map) {
+ for (auto const& gpu_accuracy_pair : ConfigurationShared::gpu_accuracy_texts_map) {
if (gpu_accuracy_pair.first == Settings::GpuAccuracy::Extreme) {
continue;
}
@@ -1228,7 +1236,8 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) {
QMenu context_menu;
- for (auto const& renderer_backend_pair : Config::renderer_backend_texts_map) {
+ for (auto const& renderer_backend_pair :
+ ConfigurationShared::renderer_backend_texts_map) {
if (renderer_backend_pair.first == Settings::RendererBackend::Null) {
continue;
}
@@ -1293,16 +1302,17 @@ void GMainWindow::InitializeRecentFileMenuActions() {
void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name,
const bool tas_allowed) {
- static const QString main_window = QStringLiteral("Main Window");
- action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name));
- action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name));
+ static const auto main_window = std::string("Main Window");
+ action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name.toStdString()));
+ action->setShortcutContext(
+ hotkey_registry.GetShortcutContext(main_window, action_name.toStdString()));
action->setAutoRepeat(false);
this->addAction(action);
auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
const auto* controller_hotkey =
- hotkey_registry.GetControllerHotkey(main_window, action_name, controller);
+ hotkey_registry.GetControllerHotkey(main_window, action_name.toStdString(), controller);
connect(
controller_hotkey, &ControllerShortcut::Activated, this,
[action, tas_allowed, this] {
@@ -1334,10 +1344,11 @@ void GMainWindow::InitializeHotkeys() {
static const QString main_window = QStringLiteral("Main Window");
const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) {
- const auto* hotkey = hotkey_registry.GetHotkey(main_window, action_name, this);
+ const auto* hotkey =
+ hotkey_registry.GetHotkey(main_window.toStdString(), action_name.toStdString(), this);
auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
- const auto* controller_hotkey =
- hotkey_registry.GetControllerHotkey(main_window, action_name, controller);
+ const auto* controller_hotkey = hotkey_registry.GetControllerHotkey(
+ main_window.toStdString(), action_name.toStdString(), controller);
connect(hotkey, &QShortcut::activated, this, function);
connect(controller_hotkey, &ControllerShortcut::Activated, this, function,
Qt::QueuedConnection);
@@ -1574,6 +1585,7 @@ void GMainWindow::ConnectMenuEvents() {
connect_menu(ui->action_Load_Cabinet_Formatter,
[this]() { OnCabinet(Service::NFP::CabinetMode::StartFormatter); });
connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit);
+ connect_menu(ui->action_Open_Controller_Menu, &GMainWindow::OnOpenControllerMenu);
connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot);
// TAS
@@ -1601,14 +1613,13 @@ void GMainWindow::UpdateMenuState() {
ui->action_Pause,
};
- const std::array applet_actions{
- ui->action_Load_Album,
- ui->action_Load_Cabinet_Nickname_Owner,
- ui->action_Load_Cabinet_Eraser,
- ui->action_Load_Cabinet_Restorer,
- ui->action_Load_Cabinet_Formatter,
- ui->action_Load_Mii_Edit,
- };
+ const std::array applet_actions{ui->action_Load_Album,
+ ui->action_Load_Cabinet_Nickname_Owner,
+ ui->action_Load_Cabinet_Eraser,
+ ui->action_Load_Cabinet_Restorer,
+ ui->action_Load_Cabinet_Formatter,
+ ui->action_Load_Mii_Edit,
+ ui->action_Open_Controller_Menu};
for (QAction* action : running_actions) {
action->setEnabled(emulation_running);
@@ -1908,12 +1919,16 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
StartGameType type, AmLaunchType launch_type) {
LOG_INFO(Frontend, "yuzu starting...");
- StoreRecentFile(filename); // Put the filename on top of the list
+
+ if (program_id == 0 ||
+ program_id > static_cast<u64>(Service::AM::Applets::AppletProgramId::MaxProgramId)) {
+ StoreRecentFile(filename); // Put the filename on top of the list
+ }
// Save configurations
UpdateUISettings();
game_list->SaveInterfaceLayout();
- config->Save();
+ config->SaveAllValues();
u64 title_id{0};
@@ -1931,7 +1946,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
const auto config_file_name = title_id == 0
? Common::FS::PathToUTF8String(file_path.filename())
: fmt::format("{:016X}", title_id);
- Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
+ QtConfig per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
system->HIDCore().ReloadInputDevices();
system->ApplySettings();
}
@@ -2156,6 +2171,10 @@ void GMainWindow::OnEmulationStopped() {
emu_frametime_label->setVisible(false);
renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan);
+ if (!firmware_label->text().isEmpty()) {
+ firmware_label->setVisible(true);
+ }
+
current_game_path.clear();
// When closing the game, destroy the GLWindow to clear the context after the game is closed
@@ -2174,6 +2193,7 @@ void GMainWindow::ShutdownGame() {
return;
}
+ play_time_manager->Stop();
OnShutdownBegin();
OnEmulationStopTimeExpired();
OnEmulationStopped();
@@ -2737,7 +2757,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
return;
}
- const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full);
+ const auto extracted = FileSys::ExtractRomFS(romfs);
if (extracted == nullptr) {
failed();
return;
@@ -2842,170 +2862,259 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id,
QDesktopServices::openUrl(QUrl(QStringLiteral("https://yuzu-emu.org/game/") + directory));
}
-void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& game_path,
- GameListShortcutTarget target) {
- // Get path to yuzu executable
- const QStringList args = QApplication::arguments();
- std::filesystem::path yuzu_command = args[0].toStdString();
-
- // If relative path, make it an absolute path
- if (yuzu_command.c_str()[0] == '.') {
- yuzu_command = Common::FS::GetCurrentDir() / yuzu_command;
+bool GMainWindow::CreateShortcutLink(const std::filesystem::path& shortcut_path,
+ const std::string& comment,
+ const std::filesystem::path& icon_path,
+ const std::filesystem::path& command,
+ const std::string& arguments, const std::string& categories,
+ const std::string& keywords, const std::string& name) try {
+#if defined(__linux__) || defined(__FreeBSD__) // Linux and FreeBSD
+ std::filesystem::path shortcut_path_full = shortcut_path / (name + ".desktop");
+ std::ofstream shortcut_stream(shortcut_path_full, std::ios::binary | std::ios::trunc);
+ if (!shortcut_stream.is_open()) {
+ LOG_ERROR(Frontend, "Failed to create shortcut");
+ return false;
}
-
-#if defined(__linux__)
- // Warn once if we are making a shortcut to a volatile AppImage
- const std::string appimage_ending =
- std::string(Common::g_scm_rev).substr(0, 9).append(".AppImage");
- if (yuzu_command.string().ends_with(appimage_ending) &&
- !UISettings::values.shortcut_already_warned) {
- if (QMessageBox::warning(this, tr("Create Shortcut"),
- tr("This will create a shortcut to the current AppImage. This may "
- "not work well if you update. Continue?"),
- QMessageBox::StandardButton::Ok |
- QMessageBox::StandardButton::Cancel) ==
- QMessageBox::StandardButton::Cancel) {
- return;
+ // TODO: Migrate fmt::print to std::print in futures STD C++ 23.
+ fmt::print(shortcut_stream, "[Desktop Entry]\n");
+ fmt::print(shortcut_stream, "Type=Application\n");
+ fmt::print(shortcut_stream, "Version=1.0\n");
+ fmt::print(shortcut_stream, "Name={}\n", name);
+ if (!comment.empty()) {
+ fmt::print(shortcut_stream, "Comment={}\n", comment);
+ }
+ if (std::filesystem::is_regular_file(icon_path)) {
+ fmt::print(shortcut_stream, "Icon={}\n", icon_path.string());
+ }
+ fmt::print(shortcut_stream, "TryExec={}\n", command.string());
+ fmt::print(shortcut_stream, "Exec={} {}\n", command.string(), arguments);
+ if (!categories.empty()) {
+ fmt::print(shortcut_stream, "Categories={}\n", categories);
+ }
+ if (!keywords.empty()) {
+ fmt::print(shortcut_stream, "Keywords={}\n", keywords);
+ }
+ return true;
+#elif defined(_WIN32) // Windows
+ HRESULT hr = CoInitialize(nullptr);
+ if (FAILED(hr)) {
+ LOG_ERROR(Frontend, "CoInitialize failed");
+ return false;
+ }
+ SCOPE_EXIT({ CoUninitialize(); });
+ IShellLinkW* ps1 = nullptr;
+ IPersistFile* persist_file = nullptr;
+ SCOPE_EXIT({
+ if (persist_file != nullptr) {
+ persist_file->Release();
}
- UISettings::values.shortcut_already_warned = true;
+ if (ps1 != nullptr) {
+ ps1->Release();
+ }
+ });
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
+ reinterpret_cast<void**>(&ps1));
+ if (FAILED(hres)) {
+ LOG_ERROR(Frontend, "Failed to create IShellLinkW instance");
+ return false;
}
-#endif // __linux__
-
- std::filesystem::path target_directory{};
-
- switch (target) {
- case GameListShortcutTarget::Desktop: {
- const QString desktop_path =
- QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
- target_directory = desktop_path.toUtf8().toStdString();
- break;
+ hres = ps1->SetPath(command.c_str());
+ if (FAILED(hres)) {
+ LOG_ERROR(Frontend, "Failed to set path");
+ return false;
}
- case GameListShortcutTarget::Applications: {
- const QString applications_path =
- QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
- if (applications_path.isEmpty()) {
- const char* home = std::getenv("HOME");
- if (home != nullptr) {
- target_directory = std::filesystem::path(home) / ".local/share/applications";
- }
- } else {
- target_directory = applications_path.toUtf8().toStdString();
+ if (!arguments.empty()) {
+ hres = ps1->SetArguments(Common::UTF8ToUTF16W(arguments).data());
+ if (FAILED(hres)) {
+ LOG_ERROR(Frontend, "Failed to set arguments");
+ return false;
}
- break;
}
- default:
- return;
+ if (!comment.empty()) {
+ hres = ps1->SetDescription(Common::UTF8ToUTF16W(comment).data());
+ if (FAILED(hres)) {
+ LOG_ERROR(Frontend, "Failed to set description");
+ return false;
+ }
}
-
- const QDir dir(QString::fromStdString(target_directory.generic_string()));
- if (!dir.exists()) {
- QMessageBox::critical(this, tr("Create Shortcut"),
- tr("Cannot create shortcut. Path \"%1\" does not exist.")
- .arg(QString::fromStdString(target_directory.generic_string())),
- QMessageBox::StandardButton::Ok);
- return;
+ if (std::filesystem::is_regular_file(icon_path)) {
+ hres = ps1->SetIconLocation(icon_path.c_str(), 0);
+ if (FAILED(hres)) {
+ LOG_ERROR(Frontend, "Failed to set icon location");
+ return false;
+ }
}
+ hres = ps1->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&persist_file));
+ if (FAILED(hres)) {
+ LOG_ERROR(Frontend, "Failed to get IPersistFile interface");
+ return false;
+ }
+ hres = persist_file->Save(std::filesystem::path{shortcut_path / (name + ".lnk")}.c_str(), TRUE);
+ if (FAILED(hres)) {
+ LOG_ERROR(Frontend, "Failed to save shortcut");
+ return false;
+ }
+ return true;
+#else // Unsupported platform
+ return false;
+#endif
+} catch (const std::exception& e) {
+ LOG_ERROR(Frontend, "Failed to create shortcut: {}", e.what());
+ return false;
+}
+// Messages in pre-defined message boxes for less code spaghetti
+bool GMainWindow::CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title) {
+ int result = 0;
+ QMessageBox::StandardButtons buttons;
+ switch (imsg) {
+ case GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES:
+ buttons = QMessageBox::Yes | QMessageBox::No;
+ result =
+ QMessageBox::information(parent, tr("Create Shortcut"),
+ tr("Do you want to launch the game in fullscreen?"), buttons);
+ return result == QMessageBox::Yes;
+ case GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS:
+ QMessageBox::information(parent, tr("Create Shortcut"),
+ tr("Successfully created a shortcut to %1").arg(game_title));
+ return false;
+ case GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING:
+ buttons = QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel;
+ result =
+ QMessageBox::warning(this, tr("Create Shortcut"),
+ tr("This will create a shortcut to the current AppImage. This may "
+ "not work well if you update. Continue?"),
+ buttons);
+ return result == QMessageBox::Ok;
+ default:
+ buttons = QMessageBox::Ok;
+ QMessageBox::critical(parent, tr("Create Shortcut"),
+ tr("Failed to create a shortcut to %1").arg(game_title), buttons);
+ return false;
+ }
+}
- const std::string game_file_name = std::filesystem::path(game_path).filename().string();
- // Determine full paths for icon and shortcut
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
- const char* home = std::getenv("HOME");
- const std::filesystem::path home_path = (home == nullptr ? "~" : home);
- const char* xdg_data_home = std::getenv("XDG_DATA_HOME");
-
- std::filesystem::path system_icons_path =
- (xdg_data_home == nullptr ? home_path / ".local/share/"
- : std::filesystem::path(xdg_data_home)) /
- "icons/hicolor/256x256";
- if (!Common::FS::CreateDirs(system_icons_path)) {
+bool GMainWindow::MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
+ std::filesystem::path& out_icon_path) {
+ // Get path to Yuzu icons directory & icon extension
+ std::string ico_extension = "png";
+#if defined(_WIN32)
+ out_icon_path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::IconsDir);
+ ico_extension = "ico";
+#elif defined(__linux__) || defined(__FreeBSD__)
+ out_icon_path = Common::FS::GetDataDirectory("XDG_DATA_HOME") / "icons/hicolor/256x256";
+#endif
+ // Create icons directory if it doesn't exist
+ if (!Common::FS::CreateDirs(out_icon_path)) {
QMessageBox::critical(
this, tr("Create Icon"),
tr("Cannot create icon file. Path \"%1\" does not exist and cannot be created.")
- .arg(QString::fromStdString(system_icons_path)),
+ .arg(QString::fromStdString(out_icon_path.string())),
QMessageBox::StandardButton::Ok);
- return;
+ out_icon_path.clear();
+ return false;
}
- std::filesystem::path icon_path =
- system_icons_path / (program_id == 0 ? fmt::format("yuzu-{}.png", game_file_name)
- : fmt::format("yuzu-{:016X}.png", program_id));
- const std::filesystem::path shortcut_path =
- target_directory / (program_id == 0 ? fmt::format("yuzu-{}.desktop", game_file_name)
- : fmt::format("yuzu-{:016X}.desktop", program_id));
-#elif defined(WIN32)
- std::filesystem::path icons_path =
- Common::FS::GetYuzuPathString(Common::FS::YuzuPath::IconsDir);
- std::filesystem::path icon_path =
- icons_path / ((program_id == 0 ? fmt::format("yuzu-{}.ico", game_file_name)
- : fmt::format("yuzu-{:016X}.ico", program_id)));
-#else
- std::string icon_extension;
-#endif
-
- // Get title from game file
- const FileSys::PatchManager pm{program_id, system->GetFileSystemController(),
- system->GetContentProvider()};
- const auto control = pm.GetControlMetadata();
- const auto loader = Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::Mode::Read));
- std::string title{fmt::format("{:016X}", program_id)};
-
- if (control.first != nullptr) {
- title = control.first->GetApplicationName();
- } else {
- loader->ReadTitle(title);
- }
+ // Create icon file path
+ out_icon_path /= (program_id == 0 ? fmt::format("yuzu-{}.{}", game_file_name, ico_extension)
+ : fmt::format("yuzu-{:016X}.{}", program_id, ico_extension));
+ return true;
+}
- // Get icon from game file
- std::vector<u8> icon_image_file{};
- if (control.second != nullptr) {
- icon_image_file = control.second->ReadAllBytes();
- } else if (loader->ReadIcon(icon_image_file) != Loader::ResultStatus::Success) {
- LOG_WARNING(Frontend, "Could not read icon from {:s}", game_path);
+void GMainWindow::OnGameListCreateShortcut(u64 program_id, const std::string& game_path,
+ GameListShortcutTarget target) {
+ std::string game_title;
+ QString qt_game_title;
+ std::filesystem::path out_icon_path;
+ // Get path to yuzu executable
+ const QStringList args = QApplication::arguments();
+ std::filesystem::path yuzu_command = args[0].toStdString();
+ // If relative path, make it an absolute path
+ if (yuzu_command.c_str()[0] == '.') {
+ yuzu_command = Common::FS::GetCurrentDir() / yuzu_command;
}
-
- QImage icon_data =
- QImage::fromData(icon_image_file.data(), static_cast<int>(icon_image_file.size()));
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
- // Convert and write the icon as a PNG
- if (!icon_data.save(QString::fromStdString(icon_path.string()))) {
- LOG_ERROR(Frontend, "Could not write icon as PNG to file");
+ // Shortcut path
+ std::filesystem::path shortcut_path{};
+ if (target == GameListShortcutTarget::Desktop) {
+ shortcut_path =
+ QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).toStdString();
+ } else if (target == GameListShortcutTarget::Applications) {
+ shortcut_path =
+ QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString();
+ }
+ // Icon path and title
+ if (std::filesystem::exists(shortcut_path)) {
+ // Get title from game file
+ const FileSys::PatchManager pm{program_id, system->GetFileSystemController(),
+ system->GetContentProvider()};
+ const auto control = pm.GetControlMetadata();
+ const auto loader =
+ Loader::GetLoader(*system, vfs->OpenFile(game_path, FileSys::Mode::Read));
+ game_title = fmt::format("{:016X}", program_id);
+ if (control.first != nullptr) {
+ game_title = control.first->GetApplicationName();
+ } else {
+ loader->ReadTitle(game_title);
+ }
+ // Delete illegal characters from title
+ const std::string illegal_chars = "<>:\"/\\|?*.";
+ for (auto it = game_title.rbegin(); it != game_title.rend(); ++it) {
+ if (illegal_chars.find(*it) != std::string::npos) {
+ game_title.erase(it.base() - 1);
+ }
+ }
+ qt_game_title = QString::fromStdString(game_title);
+ // Get icon from game file
+ std::vector<u8> icon_image_file{};
+ if (control.second != nullptr) {
+ icon_image_file = control.second->ReadAllBytes();
+ } else if (loader->ReadIcon(icon_image_file) != Loader::ResultStatus::Success) {
+ LOG_WARNING(Frontend, "Could not read icon from {:s}", game_path);
+ }
+ QImage icon_data =
+ QImage::fromData(icon_image_file.data(), static_cast<int>(icon_image_file.size()));
+ if (GMainWindow::MakeShortcutIcoPath(program_id, game_title, out_icon_path)) {
+ if (!SaveIconToFile(out_icon_path, icon_data)) {
+ LOG_ERROR(Frontend, "Could not write icon to file");
+ }
+ }
} else {
- LOG_INFO(Frontend, "Wrote an icon to {}", icon_path.string());
- }
-#elif defined(WIN32)
- if (!SaveIconToFile(icon_path.string(), icon_data)) {
- LOG_ERROR(Frontend, "Could not write icon to file");
+ GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR,
+ qt_game_title);
+ LOG_ERROR(Frontend, "Invalid shortcut target");
return;
}
+#if defined(__linux__)
+ // Special case for AppImages
+ // Warn once if we are making a shortcut to a volatile AppImage
+ const std::string appimage_ending =
+ std::string(Common::g_scm_rev).substr(0, 9).append(".AppImage");
+ if (yuzu_command.string().ends_with(appimage_ending) &&
+ !UISettings::values.shortcut_already_warned) {
+ if (GMainWindow::CreateShortcutMessagesGUI(
+ this, GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING, qt_game_title)) {
+ return;
+ }
+ UISettings::values.shortcut_already_warned = true;
+ }
#endif // __linux__
-
-#ifdef _WIN32
- // Replace characters that are illegal in Windows filenames by a dash
- const std::string illegal_chars = "<>:\"/\\|?*";
- for (char c : illegal_chars) {
- std::replace(title.begin(), title.end(), c, '_');
+ // Create shortcut
+ std::string arguments = fmt::format("-g \"{:s}\"", game_path);
+ if (GMainWindow::CreateShortcutMessagesGUI(
+ this, GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, qt_game_title)) {
+ arguments = "-f " + arguments;
}
- const std::filesystem::path shortcut_path = target_directory / (title + ".lnk").c_str();
-#endif
-
- const std::string comment =
- tr("Start %1 with the yuzu Emulator").arg(QString::fromStdString(title)).toStdString();
- const std::string arguments = fmt::format("-g \"{:s}\"", game_path);
+ const std::string comment = fmt::format("Start {:s} with the yuzu Emulator", game_title);
const std::string categories = "Game;Emulator;Qt;";
const std::string keywords = "Switch;Nintendo;";
- if (!CreateShortcut(shortcut_path.string(), title, comment, icon_path.string(),
- yuzu_command.string(), arguments, categories, keywords)) {
- QMessageBox::critical(this, tr("Create Shortcut"),
- tr("Failed to create a shortcut at %1")
- .arg(QString::fromStdString(shortcut_path.string())));
+ if (GMainWindow::CreateShortcutLink(shortcut_path, comment, out_icon_path, yuzu_command,
+ arguments, categories, keywords, game_title)) {
+ GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS,
+ qt_game_title);
return;
}
-
- LOG_INFO(Frontend, "Wrote a shortcut to {}", shortcut_path.string());
- QMessageBox::information(
- this, tr("Create Shortcut"),
- tr("Successfully created a shortcut to %1").arg(QString::fromStdString(title)));
+ GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR,
+ qt_game_title);
}
void GMainWindow::OnGameListOpenDirectory(const QString& directory) {
@@ -3040,7 +3149,7 @@ void GMainWindow::OnGameListAddDirectory() {
return;
}
- UISettings::GameDir game_dir{dir_path, false, true};
+ UISettings::GameDir game_dir{dir_path.toStdString(), false, true};
if (!UISettings::values.game_dirs.contains(game_dir)) {
UISettings::values.game_dirs.append(game_dir);
game_list->PopulateAsync(UISettings::values.game_dirs);
@@ -3086,14 +3195,14 @@ void GMainWindow::OnMenuLoadFile() {
"%1 is an identifier for the Switch executable file extensions.")
.arg(extensions);
const QString filename = QFileDialog::getOpenFileName(
- this, tr("Load File"), UISettings::values.roms_path, file_filter);
+ this, tr("Load File"), QString::fromStdString(UISettings::values.roms_path), file_filter);
is_load_file_select_active = false;
if (filename.isEmpty()) {
return;
}
- UISettings::values.roms_path = QFileInfo(filename).path();
+ UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
BootGame(filename);
}
@@ -3126,7 +3235,8 @@ void GMainWindow::OnMenuInstallToNAND() {
"Image (*.xci)");
QStringList filenames = QFileDialog::getOpenFileNames(
- this, tr("Install Files"), UISettings::values.roms_path, file_filter);
+ this, tr("Install Files"), QString::fromStdString(UISettings::values.roms_path),
+ file_filter);
if (filenames.isEmpty()) {
return;
@@ -3144,7 +3254,7 @@ void GMainWindow::OnMenuInstallToNAND() {
}
// Save folder location of the first selected file
- UISettings::values.roms_path = QFileInfo(filenames[0]).path();
+ UISettings::values.roms_path = QFileInfo(filenames[0]).path().toStdString();
int remaining = filenames.size();
@@ -3484,12 +3594,12 @@ void GMainWindow::OnExecuteProgram(std::size_t program_index) {
}
void GMainWindow::OnExit() {
- OnStopGame();
+ ShutdownGame();
}
void GMainWindow::OnSaveConfig() {
system->ApplySettings();
- config->Save();
+ config->SaveAllValues();
}
void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
@@ -3745,7 +3855,7 @@ void GMainWindow::OnConfigure() {
Settings::values.disabled_addons.clear();
- config = std::make_unique<Config>();
+ config = std::make_unique<QtConfig>();
UISettings::values.reset_to_defaults = false;
UISettings::values.game_dirs = std::move(old_game_dirs);
@@ -3780,7 +3890,7 @@ void GMainWindow::OnConfigure() {
UISettings::values.configuration_applied = false;
- config->Save();
+ config->SaveAllValues();
if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) {
render_window->installEventFilter(render_window);
@@ -3996,68 +4106,8 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
UISettings::values.configuration_applied = false;
if (!is_powered_on) {
- config->Save();
- }
-}
-
-bool GMainWindow::CreateShortcut(const std::string& shortcut_path, const std::string& title,
- const std::string& comment, const std::string& icon_path,
- const std::string& command, const std::string& arguments,
- const std::string& categories, const std::string& keywords) {
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
- // This desktop file template was writing referencing
- // https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html
- std::string shortcut_contents{};
- shortcut_contents.append("[Desktop Entry]\n");
- shortcut_contents.append("Type=Application\n");
- shortcut_contents.append("Version=1.0\n");
- shortcut_contents.append(fmt::format("Name={:s}\n", title));
- shortcut_contents.append(fmt::format("Comment={:s}\n", comment));
- shortcut_contents.append(fmt::format("Icon={:s}\n", icon_path));
- shortcut_contents.append(fmt::format("TryExec={:s}\n", command));
- shortcut_contents.append(fmt::format("Exec={:s} {:s}\n", command, arguments));
- shortcut_contents.append(fmt::format("Categories={:s}\n", categories));
- shortcut_contents.append(fmt::format("Keywords={:s}\n", keywords));
-
- std::ofstream shortcut_stream(shortcut_path);
- if (!shortcut_stream.is_open()) {
- LOG_WARNING(Common, "Failed to create file {:s}", shortcut_path);
- return false;
+ config->SaveAllValues();
}
- shortcut_stream << shortcut_contents;
- shortcut_stream.close();
-
- return true;
-#elif defined(WIN32)
- IShellLinkW* shell_link;
- auto hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
- (void**)&shell_link);
- if (FAILED(hres)) {
- return false;
- }
- shell_link->SetPath(
- Common::UTF8ToUTF16W(command).data()); // Path to the object we are referring to
- shell_link->SetArguments(Common::UTF8ToUTF16W(arguments).data());
- shell_link->SetDescription(Common::UTF8ToUTF16W(comment).data());
- shell_link->SetIconLocation(Common::UTF8ToUTF16W(icon_path).data(), 0);
-
- IPersistFile* persist_file;
- hres = shell_link->QueryInterface(IID_IPersistFile, (void**)&persist_file);
- if (FAILED(hres)) {
- return false;
- }
-
- hres = persist_file->Save(Common::UTF8ToUTF16W(shortcut_path).data(), TRUE);
- if (FAILED(hres)) {
- return false;
- }
-
- persist_file->Release();
- shell_link->Release();
-
- return true;
-#endif
- return false;
}
void GMainWindow::OnLoadAmiibo() {
@@ -4098,7 +4148,6 @@ void GMainWindow::OnLoadAmiibo() {
bool GMainWindow::question(QWidget* parent, const QString& title, const QString& text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton) {
-
QMessageBox* box_dialog = new QMessageBox(parent);
box_dialog->setWindowTitle(title);
box_dialog->setText(text);
@@ -4272,7 +4321,7 @@ void GMainWindow::OnToggleStatusBar() {
}
void GMainWindow::OnAlbum() {
- constexpr u64 AlbumId = 0x010000000000100Dull;
+ constexpr u64 AlbumId = static_cast<u64>(Service::AM::Applets::AppletProgramId::PhotoViewer);
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
@@ -4290,12 +4339,12 @@ void GMainWindow::OnAlbum() {
system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::PhotoViewer);
const auto filename = QString::fromStdString(album_nca->GetFullPath());
- UISettings::values.roms_path = QFileInfo(filename).path();
- BootGame(filename);
+ UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
+ BootGame(filename, AlbumId);
}
void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
- constexpr u64 CabinetId = 0x0100000000001002ull;
+ constexpr u64 CabinetId = static_cast<u64>(Service::AM::Applets::AppletProgramId::Cabinet);
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
@@ -4314,12 +4363,12 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
system->GetAppletManager().SetCabinetMode(mode);
const auto filename = QString::fromStdString(cabinet_nca->GetFullPath());
- UISettings::values.roms_path = QFileInfo(filename).path();
- BootGame(filename);
+ UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
+ BootGame(filename, CabinetId);
}
void GMainWindow::OnMiiEdit() {
- constexpr u64 MiiEditId = 0x0100000000001009ull;
+ constexpr u64 MiiEditId = static_cast<u64>(Service::AM::Applets::AppletProgramId::MiiEdit);
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
@@ -4337,8 +4386,33 @@ void GMainWindow::OnMiiEdit() {
system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::MiiEdit);
const auto filename = QString::fromStdString((mii_applet_nca->GetFullPath()));
- UISettings::values.roms_path = QFileInfo(filename).path();
- BootGame(filename);
+ UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
+ BootGame(filename, MiiEditId);
+}
+
+void GMainWindow::OnOpenControllerMenu() {
+ constexpr u64 ControllerAppletId =
+ static_cast<u64>(Service::AM::Applets::AppletProgramId::Controller);
+ auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ if (!bis_system) {
+ QMessageBox::warning(this, tr("No firmware available"),
+ tr("Please install the firmware to use the Controller Menu."));
+ return;
+ }
+
+ auto controller_applet_nca =
+ bis_system->GetEntry(ControllerAppletId, FileSys::ContentRecordType::Program);
+ if (!controller_applet_nca) {
+ QMessageBox::warning(this, tr("Controller Applet"),
+ tr("Controller Menu is not available. Please reinstall firmware."));
+ return;
+ }
+
+ system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::Controller);
+
+ const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath()));
+ UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
+ BootGame(filename, ControllerAppletId);
}
void GMainWindow::OnCaptureScreenshot() {
@@ -4527,11 +4601,13 @@ void GMainWindow::UpdateStatusBar() {
emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue());
game_fps_label->setVisible(true);
emu_frametime_label->setVisible(true);
+ firmware_label->setVisible(false);
}
void GMainWindow::UpdateGPUAccuracyButton() {
const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue();
- const auto gpu_accuracy_text = Config::gpu_accuracy_texts_map.find(gpu_accuracy)->second;
+ const auto gpu_accuracy_text =
+ ConfigurationShared::gpu_accuracy_texts_map.find(gpu_accuracy)->second;
gpu_accuracy_button->setText(gpu_accuracy_text.toUpper());
gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GpuAccuracy::Normal);
}
@@ -4540,31 +4616,32 @@ void GMainWindow::UpdateDockedButton() {
const auto console_mode = Settings::values.use_docked_mode.GetValue();
dock_status_button->setChecked(Settings::IsDockedMode());
dock_status_button->setText(
- Config::use_docked_mode_texts_map.find(console_mode)->second.toUpper());
+ ConfigurationShared::use_docked_mode_texts_map.find(console_mode)->second.toUpper());
}
void GMainWindow::UpdateAPIText() {
const auto api = Settings::values.renderer_backend.GetValue();
- const auto renderer_status_text = Config::renderer_backend_texts_map.find(api)->second;
+ const auto renderer_status_text =
+ ConfigurationShared::renderer_backend_texts_map.find(api)->second;
renderer_status_button->setText(
api == Settings::RendererBackend::OpenGL
- ? tr("%1 %2").arg(
- renderer_status_text.toUpper(),
- Config::shader_backend_texts_map.find(Settings::values.shader_backend.GetValue())
- ->second)
+ ? tr("%1 %2").arg(renderer_status_text.toUpper(),
+ ConfigurationShared::shader_backend_texts_map
+ .find(Settings::values.shader_backend.GetValue())
+ ->second)
: renderer_status_text.toUpper());
}
void GMainWindow::UpdateFilterText() {
const auto filter = Settings::values.scaling_filter.GetValue();
- const auto filter_text = Config::scaling_filter_texts_map.find(filter)->second;
+ const auto filter_text = ConfigurationShared::scaling_filter_texts_map.find(filter)->second;
filter_status_button->setText(filter == Settings::ScalingFilter::Fsr ? tr("FSR")
: filter_text.toUpper());
}
void GMainWindow::UpdateAAText() {
const auto aa_mode = Settings::values.anti_aliasing.GetValue();
- const auto aa_text = Config::anti_aliasing_texts_map.find(aa_mode)->second;
+ const auto aa_text = ConfigurationShared::anti_aliasing_texts_map.find(aa_mode)->second;
aa_status_button->setText(aa_mode == Settings::AntiAliasing::None
? QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "NO AA"))
: aa_text.toUpper());
@@ -4744,6 +4821,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
"games."));
}
+ SetFirmwareVersion();
+
if (behavior == ReinitializeKeyBehavior::Warning) {
game_list->PopulateAsync(UISettings::values.game_dirs);
}
@@ -4771,7 +4850,7 @@ bool GMainWindow::CheckSystemArchiveDecryption() {
}
bool GMainWindow::CheckFirmwarePresence() {
- constexpr u64 MiiEditId = 0x0100000000001009ull;
+ constexpr u64 MiiEditId = static_cast<u64>(Service::AM::Applets::AppletProgramId::MiiEdit);
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
@@ -4786,6 +4865,28 @@ bool GMainWindow::CheckFirmwarePresence() {
return true;
}
+void GMainWindow::SetFirmwareVersion() {
+ Service::Set::FirmwareVersionFormat firmware_data{};
+ const auto result = Service::Set::GetFirmwareVersionImpl(
+ firmware_data, *system, Service::Set::GetFirmwareVersionType::Version2);
+
+ if (result.IsError() || !CheckFirmwarePresence()) {
+ LOG_INFO(Frontend, "Installed firmware: No firmware available");
+ firmware_label->setVisible(false);
+ return;
+ }
+
+ firmware_label->setVisible(true);
+
+ const std::string display_version(firmware_data.display_version.data());
+ const std::string display_title(firmware_data.display_title.data());
+
+ LOG_INFO(Frontend, "Installed firmware: {}", display_title);
+
+ firmware_label->setText(QString::fromStdString(display_version));
+ firmware_label->setToolTip(QString::fromStdString(display_title));
+}
+
bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id,
u64* selected_title_id, u8* selected_content_record_type) {
using ContentInfo = std::tuple<u64, FileSys::TitleType, FileSys::ContentRecordType>;
@@ -4847,7 +4948,12 @@ bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installe
}
bool GMainWindow::ConfirmClose() {
- if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) {
+ if (emu_thread == nullptr ||
+ UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) {
+ return true;
+ }
+ if (!system->GetExitLocked() &&
+ UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) {
return true;
}
const auto text = tr("Are you sure you want to close yuzu?");
@@ -4862,6 +4968,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
UpdateUISettings();
game_list->SaveInterfaceLayout();
+ UISettings::SaveWindowState();
hotkey_registry.SaveHotkeys();
// Unload controllers early
@@ -4952,7 +5059,7 @@ bool GMainWindow::ConfirmChangeGame() {
}
bool GMainWindow::ConfirmForceLockedExit() {
- if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) {
+ if (emu_thread == nullptr) {
return true;
}
const auto text = tr("The currently running application has requested yuzu to not exit.\n\n"
@@ -5016,9 +5123,9 @@ static void AdjustLinkColor() {
}
void GMainWindow::UpdateUITheme() {
- const QString default_theme =
- QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second);
- QString current_theme = UISettings::values.theme;
+ const QString default_theme = QString::fromUtf8(
+ UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second);
+ QString current_theme = QString::fromStdString(UISettings::values.theme);
if (current_theme.isEmpty()) {
current_theme = default_theme;
@@ -5046,7 +5153,7 @@ void GMainWindow::UpdateUITheme() {
QFile f(theme_uri);
if (!f.open(QFile::ReadOnly | QFile::Text)) {
LOG_ERROR(Frontend, "Unable to open style \"{}\", fallback to the default theme",
- UISettings::values.theme.toStdString());
+ UISettings::values.theme);
current_theme = default_theme;
}
}
@@ -5059,7 +5166,7 @@ void GMainWindow::UpdateUITheme() {
setStyleSheet(ts.readAll());
} else {
LOG_ERROR(Frontend, "Unable to set style \"{}\", stylesheet file not found",
- UISettings::values.theme.toStdString());
+ UISettings::values.theme);
qApp->setStyleSheet({});
setStyleSheet({});
}
@@ -5068,27 +5175,28 @@ void GMainWindow::UpdateUITheme() {
void GMainWindow::LoadTranslation() {
bool loaded;
- if (UISettings::values.language.isEmpty()) {
+ if (UISettings::values.language.empty()) {
// If the selected language is empty, use system locale
loaded = translator.load(QLocale(), {}, {}, QStringLiteral(":/languages/"));
} else {
// Otherwise load from the specified file
- loaded = translator.load(UISettings::values.language, QStringLiteral(":/languages/"));
+ loaded = translator.load(QString::fromStdString(UISettings::values.language),
+ QStringLiteral(":/languages/"));
}
if (loaded) {
qApp->installTranslator(&translator);
} else {
- UISettings::values.language = QStringLiteral("en");
+ UISettings::values.language = std::string("en");
}
}
void GMainWindow::OnLanguageChanged(const QString& locale) {
- if (UISettings::values.language != QStringLiteral("en")) {
+ if (UISettings::values.language != std::string("en")) {
qApp->removeTranslator(&translator);
}
- UISettings::values.language = locale;
+ UISettings::values.language = locale.toStdString();
LoadTranslation();
ui->retranslateUi(this);
multiplayer_state->retranslateUi();
@@ -5114,7 +5222,7 @@ void GMainWindow::changeEvent(QEvent* event) {
// UpdateUITheme is a decent work around
if (event->type() == QEvent::PaletteChange) {
const QPalette test_palette(qApp->palette());
- const QString current_theme = UISettings::values.theme;
+ const QString current_theme = QString::fromStdString(UISettings::values.theme);
// Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too
static QColor last_window_color;
const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
@@ -5208,7 +5316,8 @@ static void SetHighDPIAttributes() {
}
int main(int argc, char* argv[]) {
- std::unique_ptr<Config> config = std::make_unique<Config>();
+ std::unique_ptr<QtConfig> config = std::make_unique<QtConfig>();
+ UISettings::RestoreWindowState(config);
bool has_broken_vulkan = false;
bool is_child = false;
if (CheckEnvVars(&is_child)) {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index f9c6efe4f..e99d58995 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -6,6 +6,7 @@
#include <memory>
#include <optional>
+#include <filesystem>
#include <QMainWindow>
#include <QMessageBox>
#include <QPushButton>
@@ -14,6 +15,7 @@
#include "common/announce_multiplayer_room.h"
#include "common/common_types.h"
+#include "configuration/qt_config.h"
#include "input_common/drivers/tas_input.h"
#include "yuzu/compatibility_list.h"
#include "yuzu/hotkeys.h"
@@ -25,7 +27,7 @@
#include <QtDBus/QtDBus>
#endif
-class Config;
+class QtConfig;
class ClickableLabel;
class EmuThread;
class GameList;
@@ -174,10 +176,17 @@ class GMainWindow : public QMainWindow {
UI_EMU_STOPPING,
};
+ enum {
+ CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES,
+ CREATE_SHORTCUT_MSGBOX_SUCCESS,
+ CREATE_SHORTCUT_MSGBOX_ERROR,
+ CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING,
+ };
+
public:
void filterBarSetChecked(bool state);
void UpdateUITheme();
- explicit GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan);
+ explicit GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulkan);
~GMainWindow() override;
bool DropAction(QDropEvent* event);
@@ -402,6 +411,7 @@ private slots:
void OnAlbum();
void OnCabinet(Service::NFP::CabinetMode mode);
void OnMiiEdit();
+ void OnOpenControllerMenu();
void OnCaptureScreenshot();
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
void OnLanguageChanged(const QString& locale);
@@ -448,6 +458,7 @@ private:
bool CheckDarkMode();
bool CheckSystemArchiveDecryption();
bool CheckFirmwarePresence();
+ void SetFirmwareVersion();
void ConfigureFilesystemProvider(const std::string& filepath);
/**
* Open (or not) the right confirm dialog based on current setting and game exit lock
@@ -456,11 +467,14 @@ private:
bool ConfirmShutdownGame();
QString GetTasStateDescription() const;
- bool CreateShortcut(const std::string& shortcut_path, const std::string& title,
- const std::string& comment, const std::string& icon_path,
- const std::string& command, const std::string& arguments,
- const std::string& categories, const std::string& keywords);
-
+ bool CreateShortcutMessagesGUI(QWidget* parent, int imsg, const QString& game_title);
+ bool MakeShortcutIcoPath(const u64 program_id, const std::string_view game_file_name,
+ std::filesystem::path& out_icon_path);
+ bool CreateShortcutLink(const std::filesystem::path& shortcut_path, const std::string& comment,
+ const std::filesystem::path& icon_path,
+ const std::filesystem::path& command, const std::string& arguments,
+ const std::string& categories, const std::string& keywords,
+ const std::string& name);
/**
* Mimic the behavior of QMessageBox::question but link controller navigation to the dialog
* The only difference is that it returns a boolean.
@@ -499,6 +513,7 @@ private:
QLabel* game_fps_label = nullptr;
QLabel* emu_frametime_label = nullptr;
QLabel* tas_label = nullptr;
+ QLabel* firmware_label = nullptr;
QPushButton* gpu_accuracy_button = nullptr;
QPushButton* renderer_status_button = nullptr;
QPushButton* dock_status_button = nullptr;
@@ -509,7 +524,7 @@ private:
QSlider* volume_slider = nullptr;
QTimer status_bar_update_timer;
- std::unique_ptr<Config> config;
+ std::unique_ptr<QtConfig> config;
// Whether emulation is currently running in yuzu.
bool emulation_running = false;
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index 88684ffb5..e53f9951e 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -25,7 +25,7 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
- <property name="margin">
+ <property name="margin" stdset="0">
<number>0</number>
</property>
</layout>
@@ -36,7 +36,7 @@
<x>0</x>
<y>0</y>
<width>1280</width>
- <height>26</height>
+ <height>21</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@@ -162,6 +162,7 @@
<addaction name="menu_cabinet_applet"/>
<addaction name="action_Load_Album"/>
<addaction name="action_Load_Mii_Edit"/>
+ <addaction name="action_Open_Controller_Menu"/>
<addaction name="separator"/>
<addaction name="action_Capture_Screenshot"/>
<addaction name="menuTAS"/>
@@ -382,9 +383,9 @@
</property>
</action>
<action name="action_Load_Album">
- <property name="text">
- <string>Open &amp;Album</string>
- </property>
+ <property name="text">
+ <string>Open &amp;Album</string>
+ </property>
</action>
<action name="action_Load_Cabinet_Nickname_Owner">
<property name="text">
@@ -407,9 +408,9 @@
</property>
</action>
<action name="action_Load_Mii_Edit">
- <property name="text">
- <string>Open &amp;Mii Editor</string>
- </property>
+ <property name="text">
+ <string>Open &amp;Mii Editor</string>
+ </property>
</action>
<action name="action_Configure_Tas">
<property name="text">
@@ -454,6 +455,11 @@
<string>R&amp;ecord</string>
</property>
</action>
+ <action name="action_Open_Controller_Menu">
+ <property name="text">
+ <string>Open &amp;Controller Menu</string>
+ </property>
+ </action>
</widget>
<resources>
<include location="yuzu.qrc"/>
diff --git a/src/yuzu/uisettings.cpp b/src/yuzu/uisettings.cpp
index 1c833767b..7bb7e95af 100644
--- a/src/yuzu/uisettings.cpp
+++ b/src/yuzu/uisettings.cpp
@@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <QSettings>
+#include "common/fs/fs.h"
+#include "common/fs/path_util.h"
#include "yuzu/uisettings.h"
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
@@ -15,6 +18,8 @@ template class Setting<unsigned long long>;
} // namespace Settings
#endif
+namespace FS = Common::FS;
+
namespace UISettings {
const Themes themes{{
@@ -28,10 +33,8 @@ const Themes themes{{
bool IsDarkTheme() {
const auto& theme = UISettings::values.theme;
- return theme == QStringLiteral("qdarkstyle") ||
- theme == QStringLiteral("qdarkstyle_midnight_blue") ||
- theme == QStringLiteral("colorful_dark") ||
- theme == QStringLiteral("colorful_midnight_blue");
+ return theme == std::string("qdarkstyle") || theme == std::string("qdarkstyle_midnight_blue") ||
+ theme == std::string("colorful_dark") || theme == std::string("colorful_midnight_blue");
}
Values values = {};
@@ -52,4 +55,58 @@ u32 CalculateWidth(u32 height, Settings::AspectRatio ratio) {
return height * 16 / 9;
}
+void SaveWindowState() {
+ const auto window_state_config_loc =
+ FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "window_state.ini");
+
+ void(FS::CreateParentDir(window_state_config_loc));
+ QSettings config(QString::fromStdString(window_state_config_loc), QSettings::IniFormat);
+
+ config.setValue(QStringLiteral("geometry"), values.geometry);
+ config.setValue(QStringLiteral("state"), values.state);
+ config.setValue(QStringLiteral("geometryRenderWindow"), values.renderwindow_geometry);
+ config.setValue(QStringLiteral("gameListHeaderState"), values.gamelist_header_state);
+ config.setValue(QStringLiteral("microProfileDialogGeometry"), values.microprofile_geometry);
+
+ config.sync();
+}
+
+void RestoreWindowState(std::unique_ptr<QtConfig>& qtConfig) {
+ const auto window_state_config_loc =
+ FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "window_state.ini");
+
+ // Migrate window state from old location
+ if (!FS::Exists(window_state_config_loc) && qtConfig->Exists("UI", "UILayout\\geometry")) {
+ const auto config_loc =
+ FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "qt-config.ini");
+ QSettings config(QString::fromStdString(config_loc), QSettings::IniFormat);
+
+ config.beginGroup(QStringLiteral("UI"));
+ config.beginGroup(QStringLiteral("UILayout"));
+ values.geometry = config.value(QStringLiteral("geometry")).toByteArray();
+ values.state = config.value(QStringLiteral("state")).toByteArray();
+ values.renderwindow_geometry =
+ config.value(QStringLiteral("geometryRenderWindow")).toByteArray();
+ values.gamelist_header_state =
+ config.value(QStringLiteral("gameListHeaderState")).toByteArray();
+ values.microprofile_geometry =
+ config.value(QStringLiteral("microProfileDialogGeometry")).toByteArray();
+ config.endGroup();
+ config.endGroup();
+ return;
+ }
+
+ void(FS::CreateParentDir(window_state_config_loc));
+ const QSettings config(QString::fromStdString(window_state_config_loc), QSettings::IniFormat);
+
+ values.geometry = config.value(QStringLiteral("geometry")).toByteArray();
+ values.state = config.value(QStringLiteral("state")).toByteArray();
+ values.renderwindow_geometry =
+ config.value(QStringLiteral("geometryRenderWindow")).toByteArray();
+ values.gamelist_header_state =
+ config.value(QStringLiteral("gameListHeaderState")).toByteArray();
+ values.microprofile_geometry =
+ config.value(QStringLiteral("microProfileDialogGeometry")).toByteArray();
+}
+
} // namespace UISettings
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index b62ff620c..549a39e1b 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -14,6 +14,7 @@
#include "common/common_types.h"
#include "common/settings.h"
#include "common/settings_enums.h"
+#include "configuration/qt_config.h"
using Settings::Category;
using Settings::ConfirmStop;
@@ -37,15 +38,15 @@ namespace UISettings {
bool IsDarkTheme();
struct ContextualShortcut {
- QString keyseq;
- QString controller_keyseq;
+ std::string keyseq;
+ std::string controller_keyseq;
int context;
bool repeat;
};
struct Shortcut {
- QString name;
- QString group;
+ std::string name;
+ std::string group;
ContextualShortcut shortcut;
};
@@ -58,11 +59,19 @@ enum class Theme {
MidnightBlueColorful,
};
+static constexpr Theme default_theme{
+#ifdef _WIN32
+ Theme::DarkColorful
+#else
+ Theme::DefaultColorful
+#endif
+};
+
using Themes = std::array<std::pair<const char*, const char*>, 6>;
extern const Themes themes;
struct GameDir {
- QString path;
+ std::string path;
bool deep_scan = false;
bool expanded = false;
bool operator==(const GameDir& rhs) const {
@@ -93,10 +102,6 @@ struct Values {
Setting<bool> show_filter_bar{linkage, true, "showFilterBar", Category::Ui};
Setting<bool> show_status_bar{linkage, true, "showStatusBar", Category::Ui};
- Setting<bool> confirm_before_closing{
- linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default,
- true, true};
-
SwitchableSetting<ConfirmStop> confirm_before_stopping{linkage,
ConfirmStop::Ask_Always,
"confirmStop",
@@ -113,9 +118,13 @@ struct Values {
Settings::Specialization::Default,
true,
true};
- Setting<bool> mute_when_in_background{
- linkage, false, "muteWhenInBackground", Category::Audio, Settings::Specialization::Default,
- true, true};
+ Setting<bool> mute_when_in_background{linkage,
+ false,
+ "muteWhenInBackground",
+ Category::UiAudio,
+ Settings::Specialization::Default,
+ true,
+ true};
Setting<bool> hide_mouse{
linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default,
true, true};
@@ -144,15 +153,15 @@ struct Values {
Category::Screenshots};
Setting<u32> screenshot_height{linkage, 0, "screenshot_height", Category::Screenshots};
- QString roms_path;
- QString symbols_path;
- QString game_dir_deprecated;
+ std::string roms_path;
+ std::string symbols_path;
+ std::string game_dir_deprecated;
bool game_dir_deprecated_deepscan;
- QVector<UISettings::GameDir> game_dirs;
+ QVector<GameDir> game_dirs;
QStringList recent_files;
- QString language;
+ std::string language;
- QString theme;
+ std::string theme;
// Shortcut name <Shortcut, context>
std::vector<Shortcut> shortcuts;
@@ -206,6 +215,54 @@ extern Values values;
u32 CalculateWidth(u32 height, Settings::AspectRatio ratio);
+void SaveWindowState();
+void RestoreWindowState(std::unique_ptr<QtConfig>& qtConfig);
+
+// This shouldn't have anything except static initializers (no functions). So
+// QKeySequence(...).toString() is NOT ALLOWED HERE.
+// This must be in alphabetical order according to action name as it must have the same order as
+// UISetting::values.shortcuts, which is alphabetically ordered.
+// clang-format off
+const std::array<Shortcut, 23> default_hotkeys{{
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+M"), std::string("Home+Dpad_Right"), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("-"), std::string("Home+Dpad_Down"), Qt::ApplicationShortcut, true}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("="), std::string("Home+Dpad_Up"), Qt::ApplicationShortcut, true}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+P"), std::string("Screenshot"), Qt::WidgetWithChildrenShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F8"), std::string("Home+L"), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F10"), std::string("Home+X"), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change GPU Accuracy")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F9"), std::string("Home+R"), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F4"), std::string("Home+Plus"), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Esc"), std::string(""), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit yuzu")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+Q"), std::string("Home+Minus"), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F11"), std::string("Home+B"), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+O"), std::string(""), Qt::WidgetWithChildrenShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F2"), std::string("Home+A"), Qt::WidgetWithChildrenShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F6"), std::string("R+Plus+Minus"), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F5"), std::string("L+Plus+Minus"), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F7"), std::string(""), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F6"), std::string(""), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F5"), std::string(""), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Filter Bar")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F"), std::string(""), Qt::WindowShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Framerate Limit")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+U"), std::string("Home+Y"), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Mouse Panning")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F9"), std::string(""), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Renderdoc Capture")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string(""), std::string(""), Qt::ApplicationShortcut, false}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Status Bar")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+S"), std::string(""), Qt::WindowShortcut, false}},
+}};
+// clang-format on
+
} // namespace UISettings
Q_DECLARE_METATYPE(UISettings::GameDir*);
+
+// These metatype declarations cannot be in common/settings.h because core is devoid of QT
+Q_DECLARE_METATYPE(Settings::CpuAccuracy);
+Q_DECLARE_METATYPE(Settings::GpuAccuracy);
+Q_DECLARE_METATYPE(Settings::FullscreenMode);
+Q_DECLARE_METATYPE(Settings::NvdecEmulation);
+Q_DECLARE_METATYPE(Settings::ResolutionSetup);
+Q_DECLARE_METATYPE(Settings::ScalingFilter);
+Q_DECLARE_METATYPE(Settings::AntiAliasing);
+Q_DECLARE_METATYPE(Settings::RendererBackend);
+Q_DECLARE_METATYPE(Settings::ShaderBackend);
+Q_DECLARE_METATYPE(Settings::AstcRecompression);
+Q_DECLARE_METATYPE(Settings::AstcDecodeMode);
diff --git a/src/yuzu/util/util.cpp b/src/yuzu/util/util.cpp
index f2854c8ec..e22cf84bf 100644
--- a/src/yuzu/util/util.cpp
+++ b/src/yuzu/util/util.cpp
@@ -4,7 +4,10 @@
#include <array>
#include <cmath>
#include <QPainter>
+
+#include "common/logging/log.h"
#include "yuzu/util/util.h"
+
#ifdef _WIN32
#include <windows.h>
#include "common/fs/file.h"
@@ -42,7 +45,7 @@ QPixmap CreateCirclePixmapFromColor(const QColor& color) {
return circle_pixmap;
}
-bool SaveIconToFile(const std::string_view path, const QImage& image) {
+bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image) {
#if defined(WIN32)
#pragma pack(push, 2)
struct IconDir {
@@ -73,7 +76,7 @@ bool SaveIconToFile(const std::string_view path, const QImage& image) {
.id_count = static_cast<WORD>(scale_sizes.size()),
};
- Common::FS::IOFile icon_file(path, Common::FS::FileAccessMode::Write,
+ Common::FS::IOFile icon_file(icon_path.string(), Common::FS::FileAccessMode::Write,
Common::FS::FileType::BinaryFile);
if (!icon_file.IsOpen()) {
return false;
@@ -135,6 +138,14 @@ bool SaveIconToFile(const std::string_view path, const QImage& image) {
icon_file.Close();
return true;
+#elif defined(__linux__) || defined(__FreeBSD__)
+ // Convert and write the icon as a PNG
+ if (!image.save(QString::fromStdString(icon_path.string()))) {
+ LOG_ERROR(Frontend, "Could not write icon as PNG to file");
+ } else {
+ LOG_INFO(Frontend, "Wrote an icon to {}", icon_path.string());
+ }
+ return true;
#else
return false;
#endif
diff --git a/src/yuzu/util/util.h b/src/yuzu/util/util.h
index 09c14ce3f..4094cf6c2 100644
--- a/src/yuzu/util/util.h
+++ b/src/yuzu/util/util.h
@@ -3,6 +3,7 @@
#pragma once
+#include <filesystem>
#include <QFont>
#include <QString>
@@ -25,4 +26,4 @@
* @param image The image to save
* @return bool If the operation succeeded
*/
-[[nodiscard]] bool SaveIconToFile(const std::string_view path, const QImage& image);
+[[nodiscard]] bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image);
diff --git a/src/yuzu/vk_device_info.cpp b/src/yuzu/vk_device_info.cpp
index 92f10d315..ab0d39c25 100644
--- a/src/yuzu/vk_device_info.cpp
+++ b/src/yuzu/vk_device_info.cpp
@@ -31,6 +31,7 @@ void PopulateRecords(std::vector<Record>& records, QWindow* window) try {
// Create a test window with a Vulkan surface type for checking present modes.
QWindow test_window(window);
test_window.setSurfaceType(QWindow::VulkanSurface);
+ test_window.create();
auto wsi = QtCommon::GetWindowSystemInfo(&test_window);
vk::InstanceDispatch dld;
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index 46eddf423..fbeba8813 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -13,9 +13,6 @@ function(create_resource file output filename)
endfunction()
add_executable(yuzu-cmd
- config.cpp
- config.h
- default_ini.h
emu_window/emu_window_sdl2.cpp
emu_window/emu_window_sdl2.h
emu_window/emu_window_sdl2_gl.cpp
@@ -25,14 +22,16 @@ add_executable(yuzu-cmd
emu_window/emu_window_sdl2_vk.cpp
emu_window/emu_window_sdl2_vk.h
precompiled_headers.h
+ sdl_config.cpp
+ sdl_config.h
yuzu.cpp
yuzu.rc
)
create_target_directory_groups(yuzu-cmd)
-target_link_libraries(yuzu-cmd PRIVATE common core input_common)
-target_link_libraries(yuzu-cmd PRIVATE inih::INIReader glad)
+target_link_libraries(yuzu-cmd PRIVATE common core input_common frontend_common)
+target_link_libraries(yuzu-cmd PRIVATE glad)
if (MSVC)
target_link_libraries(yuzu-cmd PRIVATE getopt)
endif()
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
deleted file mode 100644
index 0d25ff400..000000000
--- a/src/yuzu_cmd/config.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-// SPDX-FileCopyrightText: 2014 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <memory>
-#include <optional>
-#include <sstream>
-#include <INIReader.h>
-#include <SDL.h>
-#include "common/fs/file.h"
-#include "common/fs/fs.h"
-#include "common/fs/path_util.h"
-#include "common/logging/log.h"
-#include "common/settings.h"
-#include "core/hle/service/acc/profile_manager.h"
-#include "input_common/main.h"
-#include "yuzu_cmd/config.h"
-#include "yuzu_cmd/default_ini.h"
-
-namespace FS = Common::FS;
-
-const std::filesystem::path default_config_path =
- FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "sdl2-config.ini";
-
-Config::Config(std::optional<std::filesystem::path> config_path)
- : sdl2_config_loc{config_path.value_or(default_config_path)},
- sdl2_config{std::make_unique<INIReader>(FS::PathToUTF8String(sdl2_config_loc))} {
- Reload();
-}
-
-Config::~Config() = default;
-
-bool Config::LoadINI(const std::string& default_contents, bool retry) {
- const auto config_loc_str = FS::PathToUTF8String(sdl2_config_loc);
- if (sdl2_config->ParseError() < 0) {
- if (retry) {
- LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...",
- config_loc_str);
-
- void(FS::CreateParentDir(sdl2_config_loc));
- void(FS::WriteStringToFile(sdl2_config_loc, FS::FileType::TextFile, default_contents));
-
- sdl2_config = std::make_unique<INIReader>(config_loc_str);
-
- return LoadINI(default_contents, false);
- }
- LOG_ERROR(Config, "Failed.");
- return false;
- }
- LOG_INFO(Config, "Successfully loaded {}", config_loc_str);
- return true;
-}
-
-static const std::array<int, Settings::NativeButton::NumButtons> default_buttons = {
- SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T,
- SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W,
- SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B,
-};
-
-static const std::array<int, Settings::NativeMotion::NumMotions> default_motions = {
- SDL_SCANCODE_7,
- SDL_SCANCODE_8,
-};
-
-static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs{{
- {
- SDL_SCANCODE_UP,
- SDL_SCANCODE_DOWN,
- SDL_SCANCODE_LEFT,
- SDL_SCANCODE_RIGHT,
- SDL_SCANCODE_D,
- },
- {
- SDL_SCANCODE_I,
- SDL_SCANCODE_K,
- SDL_SCANCODE_J,
- SDL_SCANCODE_L,
- SDL_SCANCODE_D,
- },
-}};
-
-template <>
-void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) {
- std::string setting_value = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
- if (setting_value.empty()) {
- setting_value = setting.GetDefault();
- }
- setting = std::move(setting_value);
-}
-
-template <>
-void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& setting) {
- setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
-}
-
-template <typename Type, bool ranged>
-void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) {
- setting = static_cast<Type>(sdl2_config->GetInteger(group, setting.GetLabel(),
- static_cast<long>(setting.GetDefault())));
-}
-
-void Config::ReadCategory(Settings::Category category) {
- for (const auto setting : Settings::values.linkage.by_category[category]) {
- const char* category_name = [&]() {
- if (category == Settings::Category::Controls) {
- // For compatibility with older configs
- return "ControlsGeneral";
- } else {
- return Settings::TranslateCategory(category);
- }
- }();
- std::string setting_value =
- sdl2_config->Get(category_name, setting->GetLabel(), setting->DefaultToString());
- setting->LoadString(setting_value);
- }
-}
-
-void Config::ReadValues() {
- // Controls
- ReadCategory(Settings::Category::Controls);
-
- for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
- auto& player = Settings::values.players.GetValue()[p];
-
- const auto group = fmt::format("ControlsP{}", p);
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- player.buttons[i] =
- sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param);
- if (player.buttons[i].empty()) {
- player.buttons[i] = default_param;
- }
- }
-
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_analogs[i][4], 0.5f);
- player.analogs[i] =
- sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param);
- if (player.analogs[i].empty()) {
- player.analogs[i] = default_param;
- }
- }
-
- for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
- const std::string default_param =
- InputCommon::GenerateKeyboardParam(default_motions[i]);
- auto& player_motions = player.motions[i];
-
- player_motions =
- sdl2_config->Get(group, Settings::NativeMotion::mapping[i], default_param);
- if (player_motions.empty()) {
- player_motions = default_param;
- }
- }
-
- player.connected = sdl2_config->GetBoolean(group, "connected", false);
- }
-
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- Settings::values.debug_pad_buttons[i] = sdl2_config->Get(
- "ControlsGeneral", std::string("debug_pad_") + Settings::NativeButton::mapping[i],
- default_param);
- if (Settings::values.debug_pad_buttons[i].empty())
- Settings::values.debug_pad_buttons[i] = default_param;
- }
-
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_analogs[i][4], 0.5f);
- Settings::values.debug_pad_analogs[i] = sdl2_config->Get(
- "ControlsGeneral", std::string("debug_pad_") + Settings::NativeAnalog::mapping[i],
- default_param);
- if (Settings::values.debug_pad_analogs[i].empty())
- Settings::values.debug_pad_analogs[i] = default_param;
- }
-
- Settings::values.touchscreen.enabled =
- sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
- Settings::values.touchscreen.rotation_angle =
- sdl2_config->GetInteger("ControlsGeneral", "touch_angle", 0);
- Settings::values.touchscreen.diameter_x =
- sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15);
- Settings::values.touchscreen.diameter_y =
- sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15);
-
- int num_touch_from_button_maps =
- sdl2_config->GetInteger("ControlsGeneral", "touch_from_button_map", 0);
- if (num_touch_from_button_maps > 0) {
- for (int i = 0; i < num_touch_from_button_maps; ++i) {
- Settings::TouchFromButtonMap map;
- map.name = sdl2_config->Get("ControlsGeneral",
- std::string("touch_from_button_maps_") + std::to_string(i) +
- std::string("_name"),
- "default");
- const int num_touch_maps = sdl2_config->GetInteger(
- "ControlsGeneral",
- std::string("touch_from_button_maps_") + std::to_string(i) + std::string("_count"),
- 0);
- map.buttons.reserve(num_touch_maps);
-
- for (int j = 0; j < num_touch_maps; ++j) {
- std::string touch_mapping =
- sdl2_config->Get("ControlsGeneral",
- std::string("touch_from_button_maps_") + std::to_string(i) +
- std::string("_bind_") + std::to_string(j),
- "");
- map.buttons.emplace_back(std::move(touch_mapping));
- }
-
- Settings::values.touch_from_button_maps.emplace_back(std::move(map));
- }
- } else {
- Settings::values.touch_from_button_maps.emplace_back(
- Settings::TouchFromButtonMap{"default", {}});
- num_touch_from_button_maps = 1;
- }
- Settings::values.touch_from_button_map_index = std::clamp(
- Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
-
- ReadCategory(Settings::Category::Audio);
- ReadCategory(Settings::Category::Core);
- ReadCategory(Settings::Category::Cpu);
- ReadCategory(Settings::Category::CpuDebug);
- ReadCategory(Settings::Category::CpuUnsafe);
- ReadCategory(Settings::Category::Renderer);
- ReadCategory(Settings::Category::RendererAdvanced);
- ReadCategory(Settings::Category::RendererDebug);
- ReadCategory(Settings::Category::System);
- ReadCategory(Settings::Category::SystemAudio);
- ReadCategory(Settings::Category::DataStorage);
- ReadCategory(Settings::Category::Debugging);
- ReadCategory(Settings::Category::DebuggingGraphics);
- ReadCategory(Settings::Category::Miscellaneous);
- ReadCategory(Settings::Category::Network);
- ReadCategory(Settings::Category::WebService);
-
- // Data Storage
- FS::SetYuzuPath(FS::YuzuPath::NANDDir,
- sdl2_config->Get("Data Storage", "nand_directory",
- FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
- FS::SetYuzuPath(FS::YuzuPath::SDMCDir,
- sdl2_config->Get("Data Storage", "sdmc_directory",
- FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
- FS::SetYuzuPath(FS::YuzuPath::LoadDir,
- sdl2_config->Get("Data Storage", "load_directory",
- FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
- FS::SetYuzuPath(FS::YuzuPath::DumpDir,
- sdl2_config->Get("Data Storage", "dump_directory",
- FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
-
- // Debugging
- Settings::values.record_frame_times =
- sdl2_config->GetBoolean("Debugging", "record_frame_times", false);
-
- const auto title_list = sdl2_config->Get("AddOns", "title_ids", "");
- std::stringstream ss(title_list);
- std::string line;
- while (std::getline(ss, line, '|')) {
- const auto title_id = std::strtoul(line.c_str(), nullptr, 16);
- const auto disabled_list = sdl2_config->Get("AddOns", "disabled_" + line, "");
-
- std::stringstream inner_ss(disabled_list);
- std::string inner_line;
- std::vector<std::string> out;
- while (std::getline(inner_ss, inner_line, '|')) {
- out.push_back(inner_line);
- }
-
- Settings::values.disabled_addons.insert_or_assign(title_id, out);
- }
-}
-
-void Config::Reload() {
- LoadINI(DefaultINI::sdl2_config_file);
- ReadValues();
-}
diff --git a/src/yuzu_cmd/config.h b/src/yuzu_cmd/config.h
deleted file mode 100644
index 512591a39..000000000
--- a/src/yuzu_cmd/config.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: 2014 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <filesystem>
-#include <memory>
-#include <optional>
-#include <string>
-
-#include "common/settings.h"
-
-class INIReader;
-
-class Config {
- std::filesystem::path sdl2_config_loc;
- std::unique_ptr<INIReader> sdl2_config;
-
- bool LoadINI(const std::string& default_contents = "", bool retry = true);
- void ReadValues();
-
-public:
- explicit Config(std::optional<std::filesystem::path> config_path);
- ~Config();
-
- void Reload();
-
-private:
- /**
- * Applies a value read from the sdl2_config to a Setting.
- *
- * @param group The name of the INI group
- * @param setting The yuzu setting to modify
- */
- template <typename Type, bool ranged>
- void ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting);
- void ReadCategory(Settings::Category category);
-};
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
deleted file mode 100644
index 119e22183..000000000
--- a/src/yuzu_cmd/default_ini.h
+++ /dev/null
@@ -1,553 +0,0 @@
-// SPDX-FileCopyrightText: 2014 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-namespace DefaultINI {
-
-const char* sdl2_config_file =
- R"(
-[ControlsP0]
-# The input devices and parameters for each Switch native input
-# The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ...
-# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..."
-# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values
-
-# Indicates if this player should be connected at boot
-# 0 (default): Disabled, 1: Enabled
-connected=
-
-# for button input, the following devices are available:
-# - "keyboard" (default) for keyboard input. Required parameters:
-# - "code": the code of the key to bind
-# - "sdl" for joystick input using SDL. Required parameters:
-# - "guid": SDL identification GUID of the joystick
-# - "port": the index of the joystick to bind
-# - "button"(optional): the index of the button to bind
-# - "hat"(optional): the index of the hat to bind as direction buttons
-# - "axis"(optional): the index of the axis to bind
-# - "direction"(only used for hat): the direction name of the hat to bind. Can be "up", "down", "left" or "right"
-# - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is
-# triggered if the axis value crosses
-# - "direction"(only used for axis): "+" means the button is triggered when the axis value
-# is greater than the threshold; "-" means the button is triggered when the axis value
-# is smaller than the threshold
-button_a=
-button_b=
-button_x=
-button_y=
-button_lstick=
-button_rstick=
-button_l=
-button_r=
-button_zl=
-button_zr=
-button_plus=
-button_minus=
-button_dleft=
-button_dup=
-button_dright=
-button_ddown=
-button_lstick_left=
-button_lstick_up=
-button_lstick_right=
-button_lstick_down=
-button_sl=
-button_sr=
-button_home=
-button_screenshot=
-
-# for analog input, the following devices are available:
-# - "analog_from_button" (default) for emulating analog input from direction buttons. Required parameters:
-# - "up", "down", "left", "right": sub-devices for each direction.
-# Should be in the format as a button input devices using escape characters, for example, "engine$0keyboard$1code$00"
-# - "modifier": sub-devices as a modifier.
-# - "modifier_scale": a float number representing the applied modifier scale to the analog input.
-# Must be in range of 0.0-1.0. Defaults to 0.5
-# - "sdl" for joystick input using SDL. Required parameters:
-# - "guid": SDL identification GUID of the joystick
-# - "port": the index of the joystick to bind
-# - "axis_x": the index of the axis to bind as x-axis (default to 0)
-# - "axis_y": the index of the axis to bind as y-axis (default to 1)
-lstick=
-rstick=
-
-# for motion input, the following devices are available:
-# - "keyboard" (default) for emulating random motion input from buttons. Required parameters:
-# - "code": the code of the key to bind
-# - "sdl" for motion input using SDL. Required parameters:
-# - "guid": SDL identification GUID of the joystick
-# - "port": the index of the joystick to bind
-# - "motion": the index of the motion sensor to bind
-# - "cemuhookudp" for motion input using Cemu Hook protocol. Required parameters:
-# - "guid": the IP address of the cemu hook server encoded to a hex string. for example 192.168.0.1 = "c0a80001"
-# - "port": the port of the cemu hook server
-# - "pad": the index of the joystick
-# - "motion": the index of the motion sensor of the joystick to bind
-motionleft=
-motionright=
-
-[ControlsGeneral]
-# To use the debug_pad, prepend `debug_pad_` before each button setting above.
-# i.e. debug_pad_button_a=
-
-# Enable debug pad inputs to the guest
-# 0 (default): Disabled, 1: Enabled
-debug_pad_enabled =
-
-# Enable sdl raw input. Allows to configure up to 8 xinput controllers.
-# 0 (default): Disabled, 1: Enabled
-enable_raw_input =
-
-# Enable yuzu joycon driver instead of SDL drive.
-# 0: Disabled, 1 (default): Enabled
-enable_joycon_driver =
-
-# Emulates an analog input from buttons. Allowing to dial any angle.
-# 0 (default): Disabled, 1: Enabled
-emulate_analog_keyboard =
-
-# Whether to enable or disable vibration
-# 0: Disabled, 1 (default): Enabled
-vibration_enabled=
-
-# Whether to enable or disable accurate vibrations
-# 0 (default): Disabled, 1: Enabled
-enable_accurate_vibrations=
-
-# Enables controller motion inputs
-# 0: Disabled, 1 (default): Enabled
-motion_enabled =
-
-# Defines the udp device's touch screen coordinate system for cemuhookudp devices
-# - "min_x", "min_y", "max_x", "max_y"
-touch_device=
-
-# for mapping buttons to touch inputs.
-#touch_from_button_map=1
-#touch_from_button_maps_0_name=default
-#touch_from_button_maps_0_count=2
-#touch_from_button_maps_0_bind_0=foo
-#touch_from_button_maps_0_bind_1=bar
-# etc.
-
-# List of Cemuhook UDP servers, delimited by ','.
-# Default: 127.0.0.1:26760
-# Example: 127.0.0.1:26760,123.4.5.67:26761
-udp_input_servers =
-
-# Enable controlling an axis via a mouse input.
-# 0 (default): Off, 1: On
-mouse_panning =
-
-# Set mouse panning horizontal sensitivity.
-# Default: 50.0
-mouse_panning_x_sensitivity =
-
-# Set mouse panning vertical sensitivity.
-# Default: 50.0
-mouse_panning_y_sensitivity =
-
-# Set mouse panning deadzone horizontal counterweight.
-# Default: 0.0
-mouse_panning_deadzone_x_counterweight =
-
-# Set mouse panning deadzone vertical counterweight.
-# Default: 0.0
-mouse_panning_deadzone_y_counterweight =
-
-# Set mouse panning stick decay strength.
-# Default: 22.0
-mouse_panning_decay_strength =
-
-# Set mouse panning stick minimum decay.
-# Default: 5.0
-mouse_panning_minimum_decay =
-
-# Emulate an analog control stick from keyboard inputs.
-# 0 (default): Disabled, 1: Enabled
-emulate_analog_keyboard =
-
-# Enable mouse inputs to the guest
-# 0 (default): Disabled, 1: Enabled
-mouse_enabled =
-
-# Enable keyboard inputs to the guest
-# 0 (default): Disabled, 1: Enabled
-keyboard_enabled =
-
-)"
- R"(
-[Core]
-# Whether to use multi-core for CPU emulation
-# 0: Disabled, 1 (default): Enabled
-use_multi_core =
-
-# Enable unsafe extended guest system memory layout (8GB DRAM)
-# 0 (default): Disabled, 1: Enabled
-use_unsafe_extended_memory_layout =
-
-[Cpu]
-# Adjusts various optimizations.
-# Auto-select mode enables choice unsafe optimizations.
-# Accurate enables only safe optimizations.
-# Unsafe allows any unsafe optimizations.
-# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations
-cpu_accuracy =
-
-# Allow disabling safe optimizations.
-# 0 (default): Disabled, 1: Enabled
-cpu_debug_mode =
-
-# Enable inline page tables optimization (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_page_tables =
-
-# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_block_linking =
-
-# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_return_stack_buffer =
-
-# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_fast_dispatcher =
-
-# Enable context elimination CPU Optimization (reduce host memory use for guest context)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_context_elimination =
-
-# Enable constant propagation CPU optimization (basic IR optimization)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_const_prop =
-
-# Enable miscellaneous CPU optimizations (basic IR optimization)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_misc_ir =
-
-# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_reduce_misalign_checks =
-
-# Enable Host MMU Emulation (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_fastmem =
-
-# Enable Host MMU Emulation for exclusive memory instructions (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_fastmem_exclusives =
-
-# Enable fallback on failure of fastmem of exclusive memory instructions (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_recompile_exclusives =
-
-# Enable optimization to ignore invalid memory accesses (faster guest memory access)
-# 0: Disabled, 1 (default): Enabled
-cpuopt_ignore_memory_aborts =
-
-# Enable unfuse FMA (improve performance on CPUs without FMA)
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_unfuse_fma =
-
-# Enable faster FRSQRTE and FRECPE
-# Only enabled if cpu_accuracy is set to Unsafe.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_reduce_fp_error =
-
-# Enable faster ASIMD instructions (32 bits only)
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_ignore_standard_fpcr =
-
-# Enable inaccurate NaN handling
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_inaccurate_nan =
-
-# Disable address space checks (64 bits only)
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_fastmem_check =
-
-# Enable faster exclusive instructions
-# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
-# 0: Disabled, 1 (default): Enabled
-cpuopt_unsafe_ignore_global_monitor =
-
-)"
- R"(
-[Renderer]
-# Which backend API to use.
-# 0: OpenGL, 1 (default): Vulkan
-backend =
-
-# Whether to enable asynchronous presentation (Vulkan only)
-# 0 (default): Off, 1: On
-async_presentation =
-
-# Enable graphics API debugging mode.
-# 0 (default): Disabled, 1: Enabled
-debug =
-
-# Enable shader feedback.
-# 0 (default): Disabled, 1: Enabled
-renderer_shader_feedback =
-
-# Enable Nsight Aftermath crash dumps
-# 0 (default): Disabled, 1: Enabled
-nsight_aftermath =
-
-# Disable shader loop safety checks, executing the shader without loop logic changes
-# 0 (default): Disabled, 1: Enabled
-disable_shader_loop_safety_checks =
-
-# Which Vulkan physical device to use (defaults to 0)
-vulkan_device =
-
-# 0: 0.5x (360p/540p) [EXPERIMENTAL]
-# 1: 0.75x (540p/810p) [EXPERIMENTAL]
-# 2 (default): 1x (720p/1080p)
-# 3: 1.5x (1080p/1620p) [EXPERIMENTAL]
-# 4: 2x (1440p/2160p)
-# 5: 3x (2160p/3240p)
-# 6: 4x (2880p/4320p)
-# 7: 5x (3600p/5400p)
-# 8: 6x (4320p/6480p)
-# 9: 7x (5040p/7560p)
-# 10: 8x (5760/8640p)
-resolution_setup =
-
-# Pixel filter to use when up- or down-sampling rendered frames.
-# 0: Nearest Neighbor
-# 1 (default): Bilinear
-# 2: Bicubic
-# 3: Gaussian
-# 4: ScaleForce
-# 5: AMD FidelityFX™️ Super Resolution
-scaling_filter =
-
-# Anti-Aliasing (AA)
-# 0 (default): None, 1: FXAA, 2: SMAA
-anti_aliasing =
-
-# Whether to use fullscreen or borderless window mode
-# 0 (Windows default): Borderless window, 1 (All other default): Exclusive fullscreen
-fullscreen_mode =
-
-# Aspect ratio
-# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Force 16:10, 4: Stretch to Window
-aspect_ratio =
-
-# Anisotropic filtering
-# 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x
-max_anisotropy =
-
-# Whether to enable VSync or not.
-# OpenGL: Values other than 0 enable VSync
-# Vulkan: FIFO is selected if the requested mode is not supported by the driver.
-# FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate.
-# FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down.
-# Mailbox can have lower latency than FIFO and does not tear but may drop frames.
-# Immediate (no synchronization) just presents whatever is available and can exhibit tearing.
-# 0: Immediate (Off), 1: Mailbox, 2 (Default): FIFO (On), 3: FIFO Relaxed
-use_vsync =
-
-# Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is
-# not available and GLASM is selected, GLSL will be used.
-# 0: GLSL, 1 (default): GLASM, 2: SPIR-V
-shader_backend =
-
-# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory.
-# 0: Off, 1 (default): On
-use_reactive_flushing =
-
-# Whether to allow asynchronous shader building.
-# 0 (default): Off, 1: On
-use_asynchronous_shaders =
-
-# NVDEC emulation.
-# 0: Disabled, 1: CPU Decoding, 2 (default): GPU Decoding
-nvdec_emulation =
-
-# Accelerate ASTC texture decoding.
-# 0: Off, 1 (default): On
-accelerate_astc =
-
-# Decode ASTC textures asynchronously.
-# 0 (default): Off, 1: On
-async_astc =
-
-# Recompress ASTC textures to a different format.
-# 0 (default): Uncompressed, 1: BC1 (Low quality), 2: BC3: (Medium quality)
-async_astc =
-
-# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value
-# 0: Off, 1: On (default)
-use_speed_limit =
-
-# Limits the speed of the game to run no faster than this value as a percentage of target speed
-# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default)
-speed_limit =
-
-# Whether to use disk based shader cache
-# 0: Off, 1 (default): On
-use_disk_shader_cache =
-
-# Which gpu accuracy level to use
-# 0: Normal, 1 (default): High, 2: Extreme (Very slow)
-gpu_accuracy =
-
-# Whether to use asynchronous GPU emulation
-# 0 : Off (slow), 1 (default): On (fast)
-use_asynchronous_gpu_emulation =
-
-# Inform the guest that GPU operations completed more quickly than they did.
-# 0: Off, 1 (default): On
-use_fast_gpu_time =
-
-# Whether to use garbage collection or not for GPU caches.
-# 0 (default): Off, 1: On
-use_caches_gc =
-
-# The clear color for the renderer. What shows up on the sides of the bottom screen.
-# Must be in range of 0-255. Defaults to 0 for all.
-bg_red =
-bg_blue =
-bg_green =
-
-)"
- R"(
-[Audio]
-# Which audio output engine to use.
-# auto (default): Auto-select
-# cubeb: Cubeb audio engine (if available)
-# sdl2: SDL2 audio engine (if available)
-# null: No audio output
-output_engine =
-
-# Which audio device to use.
-# auto (default): Auto-select
-output_device =
-
-# Output volume.
-# 100 (default): 100%, 0; mute
-volume =
-
-[Data Storage]
-# Whether to create a virtual SD card.
-# 1 (default): Yes, 0: No
-use_virtual_sd =
-
-# Whether or not to enable gamecard emulation
-# 1: Yes, 0 (default): No
-gamecard_inserted =
-
-# Whether or not the gamecard should be emulated as the current game
-# If 'gamecard_inserted' is 0 this setting is irrelevant
-# 1: Yes, 0 (default): No
-gamecard_current_game =
-
-# Path to an XCI file to use as the gamecard
-# If 'gamecard_inserted' is 0 this setting is irrelevant
-# If 'gamecard_current_game' is 1 this setting is irrelevant
-gamecard_path =
-
-[System]
-# Whether the system is docked
-# 1 (default): Yes, 0: No
-use_docked_mode =
-
-# Sets the seed for the RNG generator built into the switch
-# rng_seed will be ignored and randomly generated if rng_seed_enabled is false
-rng_seed_enabled =
-rng_seed =
-
-# Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service
-# This will auto-increment, with the time set being the time the game is started
-# This override will only occur if custom_rtc_enabled is true, otherwise the current time is used
-custom_rtc_enabled =
-custom_rtc =
-
-# Sets the systems language index
-# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
-# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
-# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Brazilian Portuguese
-language_index =
-
-# The system region that yuzu will use during emulation
-# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
-region_index =
-
-# The system time zone that yuzu will use during emulation
-# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone
-time_zone_index =
-
-# Sets the sound output mode.
-# 0: Mono, 1 (default): Stereo, 2: Surround
-sound_index =
-
-[Miscellaneous]
-# A filter which removes logs below a certain logging level.
-# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical
-log_filter = *:Trace
-
-# Use developer keys
-# 0 (default): Disabled, 1: Enabled
-use_dev_keys =
-
-[Debugging]
-# Record frame time data, can be found in the log directory. Boolean value
-record_frame_times =
-# Determines whether or not yuzu will dump the ExeFS of all games it attempts to load while loading them
-dump_exefs=false
-# Determines whether or not yuzu will dump all NSOs it attempts to load while loading them
-dump_nso=false
-# Determines whether or not yuzu will save the filesystem access log.
-enable_fs_access_log=false
-# Enables verbose reporting services
-reporting_services =
-# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
-# false: Retail/Normal Mode (default), true: Kiosk Mode
-quest_flag =
-# Determines whether debug asserts should be enabled, which will throw an exception on asserts.
-# false: Disabled (default), true: Enabled
-use_debug_asserts =
-# Determines whether unimplemented HLE service calls should be automatically stubbed.
-# false: Disabled (default), true: Enabled
-use_auto_stub =
-# Enables/Disables the macro JIT compiler
-disable_macro_jit=false
-# Determines whether to enable the GDB stub and wait for the debugger to attach before running.
-# false: Disabled (default), true: Enabled
-use_gdbstub=false
-# The port to use for the GDB server, if it is enabled.
-gdbstub_port=6543
-
-[WebService]
-# Whether or not to enable telemetry
-# 0: No, 1 (default): Yes
-enable_telemetry =
-# URL for Web API
-web_api_url = https://api.yuzu-emu.org
-# Username and token for yuzu Web Service
-# See https://profile.yuzu-emu.org/ for more info
-yuzu_username =
-yuzu_token =
-
-[Network]
-# Name of the network interface device to use with yuzu LAN play.
-# e.g. On *nix: 'enp7s0', 'wlp6s0u1u3u3', 'lo'
-# e.g. On Windows: 'Ethernet', 'Wi-Fi'
-network_interface =
-
-[AddOns]
-# Used to disable add-ons
-# List of title IDs of games that will have add-ons disabled (separated by '|'):
-title_ids =
-# For each title ID, have a key/value pair called `disabled_<title_id>` equal to the names of the add-ons to disable (sep. by '|')
-# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey
-)";
-} // namespace DefaultINI
diff --git a/src/yuzu_cmd/sdl_config.cpp b/src/yuzu_cmd/sdl_config.cpp
new file mode 100644
index 000000000..39fd8050c
--- /dev/null
+++ b/src/yuzu_cmd/sdl_config.cpp
@@ -0,0 +1,257 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+// SDL will break our main function in yuzu-cmd if we don't define this before adding SDL.h
+#define SDL_MAIN_HANDLED
+#include <SDL.h>
+
+#include "input_common/main.h"
+#include "sdl_config.h"
+
+const std::array<int, Settings::NativeButton::NumButtons> SdlConfig::default_buttons = {
+ SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T,
+ SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W,
+ SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B,
+};
+
+const std::array<int, Settings::NativeMotion::NumMotions> SdlConfig::default_motions = {
+ SDL_SCANCODE_7,
+ SDL_SCANCODE_8,
+};
+
+const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> SdlConfig::default_analogs{
+ {
+ {
+ SDL_SCANCODE_UP,
+ SDL_SCANCODE_DOWN,
+ SDL_SCANCODE_LEFT,
+ SDL_SCANCODE_RIGHT,
+ },
+ {
+ SDL_SCANCODE_I,
+ SDL_SCANCODE_K,
+ SDL_SCANCODE_J,
+ SDL_SCANCODE_L,
+ },
+ }};
+
+const std::array<int, 2> SdlConfig::default_stick_mod = {
+ SDL_SCANCODE_D,
+ 0,
+};
+
+const std::array<int, 2> SdlConfig::default_ringcon_analogs{{
+ 0,
+ 0,
+}};
+
+SdlConfig::SdlConfig(const std::optional<std::string> config_path) {
+ Initialize(config_path);
+ ReadSdlValues();
+ SaveSdlValues();
+}
+
+SdlConfig::~SdlConfig() {
+ if (global) {
+ SdlConfig::SaveAllValues();
+ }
+}
+
+void SdlConfig::ReloadAllValues() {
+ Reload();
+ ReadSdlValues();
+ SaveSdlValues();
+}
+
+void SdlConfig::SaveAllValues() {
+ Save();
+ SaveSdlValues();
+}
+
+void SdlConfig::ReadSdlValues() {
+ ReadSdlControlValues();
+}
+
+void SdlConfig::ReadSdlControlValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ Settings::values.players.SetGlobal(!IsCustomConfig());
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
+ ReadSdlPlayerValues(p);
+ }
+ if (IsCustomConfig()) {
+ EndGroup();
+ return;
+ }
+ ReadDebugControlValues();
+ ReadHidbusValues();
+
+ EndGroup();
+}
+
+void SdlConfig::ReadSdlPlayerValues(const std::size_t player_index) {
+ std::string player_prefix;
+ if (type != ConfigType::InputProfile) {
+ player_prefix.append("player_").append(ToString(player_index)).append("_");
+ }
+
+ auto& player = Settings::values.players.GetValue()[player_index];
+ if (IsCustomConfig()) {
+ const auto profile_name =
+ ReadStringSetting(std::string(player_prefix).append("profile_name"));
+ if (profile_name.empty()) {
+ // Use the global input config
+ player = Settings::values.players.GetValue(true)[player_index];
+ return;
+ }
+ }
+
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ auto& player_buttons = player.buttons[i];
+
+ player_buttons = ReadStringSetting(
+ std::string(player_prefix).append(Settings::NativeButton::mapping[i]), default_param);
+ if (player_buttons.empty()) {
+ player_buttons = default_param;
+ }
+ }
+
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ auto& player_analogs = player.analogs[i];
+
+ player_analogs = ReadStringSetting(
+ std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]), default_param);
+ if (player_analogs.empty()) {
+ player_analogs = default_param;
+ }
+ }
+
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ auto& player_motions = player.motions[i];
+
+ player_motions = ReadStringSetting(
+ std::string(player_prefix).append(Settings::NativeMotion::mapping[i]), default_param);
+ if (player_motions.empty()) {
+ player_motions = default_param;
+ }
+ }
+}
+
+void SdlConfig::ReadDebugControlValues() {
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ auto& debug_pad_buttons = Settings::values.debug_pad_buttons[i];
+ debug_pad_buttons = ReadStringSetting(
+ std::string("debug_pad_").append(Settings::NativeButton::mapping[i]), default_param);
+ if (debug_pad_buttons.empty()) {
+ debug_pad_buttons = default_param;
+ }
+ }
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ auto& debug_pad_analogs = Settings::values.debug_pad_analogs[i];
+ debug_pad_analogs = ReadStringSetting(
+ std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]), default_param);
+ if (debug_pad_analogs.empty()) {
+ debug_pad_analogs = default_param;
+ }
+ }
+}
+
+void SdlConfig::ReadHidbusValues() {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ 0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
+ auto& ringcon_analogs = Settings::values.ringcon_analogs;
+
+ ringcon_analogs = ReadStringSetting(std::string("ring_controller"), default_param);
+ if (ringcon_analogs.empty()) {
+ ringcon_analogs = default_param;
+ }
+}
+
+void SdlConfig::SaveSdlValues() {
+ SaveSdlControlValues();
+
+ WriteToIni();
+}
+
+void SdlConfig::SaveSdlControlValues() {
+ BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
+
+ Settings::values.players.SetGlobal(!IsCustomConfig());
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
+ SaveSdlPlayerValues(p);
+ }
+ if (IsCustomConfig()) {
+ EndGroup();
+ return;
+ }
+ SaveDebugControlValues();
+ SaveHidbusValues();
+
+ EndGroup();
+}
+
+void SdlConfig::SaveSdlPlayerValues(const std::size_t player_index) {
+ std::string player_prefix;
+ if (type != ConfigType::InputProfile) {
+ player_prefix = std::string("player_").append(ToString(player_index)).append("_");
+ }
+
+ const auto& player = Settings::values.players.GetValue()[player_index];
+ if (IsCustomConfig() && player.profile_name.empty()) {
+ // No custom profile selected
+ return;
+ }
+
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ WriteSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]),
+ player.buttons[i], std::make_optional(default_param));
+ }
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ WriteSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]),
+ player.analogs[i], std::make_optional(default_param));
+ }
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ WriteSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]),
+ player.motions[i], std::make_optional(default_param));
+ }
+}
+
+void SdlConfig::SaveDebugControlValues() {
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ WriteSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]),
+ Settings::values.debug_pad_buttons[i], std::make_optional(default_param));
+ }
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ WriteSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]),
+ Settings::values.debug_pad_analogs[i], std::make_optional(default_param));
+ }
+}
+
+void SdlConfig::SaveHidbusValues() {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ 0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
+ WriteSetting(std::string("ring_controller"), Settings::values.ringcon_analogs,
+ std::make_optional(default_param));
+}
+
+std::vector<Settings::BasicSetting*>& SdlConfig::FindRelevantList(Settings::Category category) {
+ return Settings::values.linkage.by_category[category];
+}
diff --git a/src/yuzu_cmd/sdl_config.h b/src/yuzu_cmd/sdl_config.h
new file mode 100644
index 000000000..1fd1c692d
--- /dev/null
+++ b/src/yuzu_cmd/sdl_config.h
@@ -0,0 +1,49 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "frontend_common/config.h"
+
+class SdlConfig final : public Config {
+public:
+ explicit SdlConfig(std::optional<std::string> config_path);
+ ~SdlConfig() override;
+
+ void ReloadAllValues() override;
+ void SaveAllValues() override;
+
+protected:
+ void ReadSdlValues();
+ void ReadSdlPlayerValues(std::size_t player_index);
+ void ReadSdlControlValues();
+ void ReadHidbusValues() override;
+ void ReadDebugControlValues() override;
+ void ReadPathValues() override {}
+ void ReadShortcutValues() override {}
+ void ReadUIValues() override {}
+ void ReadUIGamelistValues() override {}
+ void ReadUILayoutValues() override {}
+ void ReadMultiplayerValues() override {}
+
+ void SaveSdlValues();
+ void SaveSdlPlayerValues(std::size_t player_index);
+ void SaveSdlControlValues();
+ void SaveHidbusValues() override;
+ void SaveDebugControlValues() override;
+ void SavePathValues() override {}
+ void SaveShortcutValues() override {}
+ void SaveUIValues() override {}
+ void SaveUIGamelistValues() override {}
+ void SaveUILayoutValues() override {}
+ void SaveMultiplayerValues() override {}
+
+ std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override;
+
+public:
+ static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
+ static const std::array<int, Settings::NativeMotion::NumMotions> default_motions;
+ static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs;
+ static const std::array<int, 2> default_stick_mod;
+ static const std::array<int, 2> default_ringcon_analogs;
+};
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 087cfaa26..0416d5951 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -29,10 +29,11 @@
#include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/loader.h"
#include "core/telemetry_session.h"
+#include "frontend_common/config.h"
#include "input_common/main.h"
#include "network/network.h"
+#include "sdl_config.h"
#include "video_core/renderer_base.h"
-#include "yuzu_cmd/config.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2_null.h"
@@ -300,7 +301,7 @@ int main(int argc, char** argv) {
}
}
- Config config{config_path};
+ SdlConfig config{config_path};
// apply the log_filter setting
// the logger was initialized before and doesn't pick up the filter on its own